refactor: 초정밀 시나리오 강화 (1060→1381 steps, 68/68 PASS)
This commit is contained in:
259
_backup_before_enhance/accounting-bad-debt.json
Normal file
259
_backup_before_enhance/accounting-bad-debt.json
Normal file
@@ -0,0 +1,259 @@
|
||||
{
|
||||
"id": "accounting-bad-debt",
|
||||
"name": "악성채권추심관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "회계관리 > 악성채권추심관리 메뉴의 악성채권 CRUD 기능 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "회계관리",
|
||||
"level2": "악성채권추심관리",
|
||||
"expectedUrl": "/accounting/bad-debt-collection",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"testData": {
|
||||
"create": {
|
||||
"vendorName": "E2E_TEST_채권거래처_{timestamp}",
|
||||
"debtAmount": "1000000",
|
||||
"status": "추심중"
|
||||
}
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 회계관리 > 악성채권추심관리",
|
||||
"action": "menu_navigate",
|
||||
"level1": "회계관리",
|
||||
"level2": "악성채권추심관리",
|
||||
"expected": {
|
||||
"url_contains": "/accounting",
|
||||
"visible": ["악성채권", "추심"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"악성채권 목록 표시",
|
||||
"채권 등록 버튼 존재",
|
||||
"상태 필터 존재"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "악성채권 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
"거래처 컬럼",
|
||||
"채권금액 컬럼",
|
||||
"발생일 컬럼",
|
||||
"상태 컬럼",
|
||||
"담당자 컬럼"
|
||||
],
|
||||
"expected": "악성채권 테이블 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"총 채권금액 표시",
|
||||
"추심중 건수",
|
||||
"회수완료 건수"
|
||||
],
|
||||
"expected": "통계 정보 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 채권 등록 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('등록'), button:has-text('추가'), button:has-text('신규')",
|
||||
"expected": {
|
||||
"modal_open": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 거래처 선택",
|
||||
"action": "click_if_exists",
|
||||
"target": "select[name*='vendor'], input[placeholder*='거래처']",
|
||||
"expected": "거래처 선택 가능"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 채권금액 입력",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[name*='amount'], input[placeholder*='금액']"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 필수 검증 #2: 채권 저장",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('저장'), button:has-text('등록'), button:has-text('확인')",
|
||||
"verify": {
|
||||
"url_maintained": true,
|
||||
"no_error_page": true,
|
||||
"api_call": "POST /api/v1/accounting/bad-debts",
|
||||
"toast": "등록|저장|완료|성공"
|
||||
},
|
||||
"expected": "채권 등록 완료"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 등록된 채권 검색",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[type='search'], input[placeholder*='검색']"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 등록된 채권 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"E2E_TEST_채권거래처 목록에 표시"
|
||||
],
|
||||
"expected": "등록된 채권 확인"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 채권 상세 조회",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:has-text('E2E_TEST_채권거래처')",
|
||||
"expected": {
|
||||
"detail_view": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "상세 정보 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"거래처 정보 표시",
|
||||
"채권금액 표시",
|
||||
"추심 이력 표시"
|
||||
],
|
||||
"expected": "상세 정보 표시"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 상태 변경",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('상태변경'), select[name*='status']",
|
||||
"expected": "상태 변경 가능"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 추심 메모 추가",
|
||||
"action": "click_if_exists",
|
||||
"target": "textarea[name*='memo'], textarea[placeholder*='메모']"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 변경 저장",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('저장'), button:has-text('확인')",
|
||||
"verify": {
|
||||
"api_call": "PUT /api/v1/accounting/bad-debts",
|
||||
"toast": "수정|저장|완료|성공"
|
||||
},
|
||||
"expected": "채권 정보 수정 완료"
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 채권 삭제",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('삭제'), button:has-text('제거')",
|
||||
"expected": {
|
||||
"confirm_dialog": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 삭제 확인",
|
||||
"action": "click_if_exists",
|
||||
"target": "[role='alertdialog'] button:has-text('확인'), [role='dialog'] button:has-text('삭제')",
|
||||
"verify": {
|
||||
"api_call": "DELETE /api/v1/accounting/bad-debts",
|
||||
"toast": "삭제|제거|완료|성공"
|
||||
},
|
||||
"expected": "채권 삭제 완료"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 삭제 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"E2E_TEST_채권거래처 목록에서 제거"
|
||||
],
|
||||
"expected": "채권 삭제 반영"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/accounting/bad-debts",
|
||||
"description": "악성채권 목록 조회"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"endpoint": "/api/v1/accounting/bad-debts",
|
||||
"description": "악성채권 등록"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/accounting/bad-debts/:id",
|
||||
"description": "악성채권 상세 조회"
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"endpoint": "/api/v1/accounting/bad-debts/:id",
|
||||
"description": "악성채권 수정"
|
||||
},
|
||||
{
|
||||
"method": "DELETE",
|
||||
"endpoint": "/api/v1/accounting/bad-debts/:id",
|
||||
"description": "악성채권 삭제"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 2,
|
||||
"name": "저장 버튼",
|
||||
"steps": [8, 15],
|
||||
"criteria": "API 호출 + 성공 토스트 + 데이터 반영"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"criteria": "악성채권 목록, 등록 버튼, 상태 필터 존재"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"onCreateFail": "등록 모달 닫고 재시도",
|
||||
"onUpdateFail": "페이지 새로고침 후 재시도",
|
||||
"onDeleteFail": "수동 삭제 필요",
|
||||
"cleanupRequired": "E2E_TEST_채권거래처* 패턴 데이터 삭제"
|
||||
}
|
||||
}
|
||||
195
_backup_before_enhance/accounting-bank-transaction.json
Normal file
195
_backup_before_enhance/accounting-bank-transaction.json
Normal file
@@ -0,0 +1,195 @@
|
||||
{
|
||||
"id": "accounting-bank-transaction",
|
||||
"name": "입출금계좌조회 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "회계관리 > 입출금계좌조회 메뉴의 계좌 거래내역 조회/필터/엑셀 기능 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "회계관리",
|
||||
"level2": "입출금계좌조회",
|
||||
"expectedUrl": "/accounting/bank-transactions",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 회계관리 > 입출금계좌조회",
|
||||
"action": "menu_navigate",
|
||||
"level1": "회계관리",
|
||||
"level2": "입출금계좌조회",
|
||||
"expected": {
|
||||
"url_contains": "/accounting",
|
||||
"visible": ["입출금", "계좌"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"거래내역 목록 표시",
|
||||
"계좌 선택 가능",
|
||||
"기간 필터 존재"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "거래내역 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
"거래일 컬럼",
|
||||
"입금 컬럼",
|
||||
"출금 컬럼",
|
||||
"잔액 컬럼",
|
||||
"적요 컬럼"
|
||||
],
|
||||
"expected": "거래내역 테이블 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "계좌 선택 드롭다운 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"계좌 선택 가능"
|
||||
],
|
||||
"expected": "계좌 선택 가능"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 기간 필터 - 시작일",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[type='date']:first-of-type, [class*='datepicker']:first-of-type",
|
||||
"expected": "날짜 선택 열림"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 기간 필터 적용",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('조회'), button:has-text('검색'), button:has-text('적용')",
|
||||
"expected": "필터 적용됨"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 필터 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"필터된 데이터 표시 또는 결과 없음"
|
||||
],
|
||||
"expected": "필터 동작 확인"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 거래 상세 보기",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:first-child",
|
||||
"expected": {
|
||||
"detail_view": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"거래일시 표시",
|
||||
"금액 표시",
|
||||
"적요 표시"
|
||||
],
|
||||
"expected": "거래 상세 정보 표시"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "목록으로 돌아가기",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('목록'), a:has-text('목록'), [class*='back']",
|
||||
"expected": "목록 페이지로 복귀"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "입금 합계 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"입금 합계 표시"
|
||||
],
|
||||
"expected": "입금 합계 표시"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "출금 합계 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"출금 합계 표시"
|
||||
],
|
||||
"expected": "출금 합계 표시"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"name": "엑셀 다운로드 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"엑셀 다운로드 버튼 존재"
|
||||
],
|
||||
"expected": "엑셀 다운로드 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"name": "인쇄 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"인쇄 버튼 존재"
|
||||
],
|
||||
"expected": "인쇄 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"name": "페이지네이션 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"페이지 번호 표시"
|
||||
],
|
||||
"expected": "페이지네이션 표시"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/accounting/bank-transactions",
|
||||
"description": "입출금 내역 조회"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/accounting/bank-accounts",
|
||||
"description": "계좌 목록 조회"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 3,
|
||||
"name": "검색/필터",
|
||||
"steps": [5, 6, 7],
|
||||
"criteria": "기간 필터 동작"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"criteria": "거래내역 목록, 계좌 선택, 기간 필터 존재"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"note": "조회 전용 페이지로 데이터 변경 없음"
|
||||
}
|
||||
}
|
||||
293
_backup_before_enhance/accounting-bill.json
Normal file
293
_backup_before_enhance/accounting-bill.json
Normal file
@@ -0,0 +1,293 @@
|
||||
{
|
||||
"id": "accounting-bill",
|
||||
"name": "어음관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "회계관리 > 어음관리 메뉴의 어음 조회/등록/수정/삭제 전체 CRUD 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "회계관리",
|
||||
"level2": "어음관리",
|
||||
"expectedUrl": "/accounting/bills",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"testData": {
|
||||
"create": {
|
||||
"billNumber": "E2E_TEST_어음",
|
||||
"amount": "1000000",
|
||||
"dueDate": "2026-03-15",
|
||||
"issuer": "테스트발행처",
|
||||
"memo": "E2E 자동화 테스트 어음"
|
||||
},
|
||||
"update": {
|
||||
"memo": "E2E 수정된 어음 메모"
|
||||
}
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 회계관리 > 어음관리",
|
||||
"action": "menu_navigate",
|
||||
"level1": "회계관리",
|
||||
"level2": "어음관리",
|
||||
"expected": {
|
||||
"url_contains": "/accounting/bills",
|
||||
"visible": ["어음관리", "어음"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"어음 목록 표시",
|
||||
"어음 등록 버튼 존재",
|
||||
"검색/필터 기능 존재"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "어음 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
"어음번호 컬럼",
|
||||
"금액 컬럼",
|
||||
"만기일 컬럼",
|
||||
"발행처 컬럼",
|
||||
"상태 컬럼"
|
||||
],
|
||||
"expected": "어음 테이블 컬럼 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "검색 기능 테스트",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[placeholder*='검색']",
|
||||
"value": "테스트",
|
||||
"expected": {
|
||||
"data_filtered": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 어음 등록 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('등록'), button:has-text('어음 등록'), button:has-text('추가')",
|
||||
"expected": {
|
||||
"modal": true,
|
||||
"modalTitle": "어음 등록"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 어음 정보 입력",
|
||||
"action": "fill_form",
|
||||
"fields": [
|
||||
{"name": "어음번호", "type": "text", "value": "E2E_TEST_어음_{timestamp}"},
|
||||
{"name": "금액", "type": "number", "value": "1000000"},
|
||||
{"name": "만기일", "type": "date", "value": "2026-03-15"},
|
||||
{"name": "발행처", "type": "text", "value": "테스트발행처"},
|
||||
{"name": "메모", "type": "text", "value": "E2E 자동화 테스트 어음"}
|
||||
],
|
||||
"note": "타임스탬프로 고유성 보장"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 필수 검증 #2: 등록 저장",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('저장'), button:has-text('등록')",
|
||||
"verify": {
|
||||
"url_maintained": true,
|
||||
"no_error_page": true,
|
||||
"api_call": "POST /api/v1/bills",
|
||||
"toast": "등록|완료|성공"
|
||||
},
|
||||
"expected": "어음 등록 완료"
|
||||
},
|
||||
{
|
||||
"id": "7-modal-close",
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 모달 닫기 확인",
|
||||
"action": "close_modal_if_open",
|
||||
"expected": "모달 닫힘"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 등록 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"search": "E2E_TEST_어음",
|
||||
"expected": {
|
||||
"row_exists": true,
|
||||
"contains": ["E2E", "1,000,000"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 어음 상세 페이지 진입",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:has-text('E2E')",
|
||||
"expected": {
|
||||
"url_contains": "/accounting/bills/",
|
||||
"visible": ["어음 상세", "수정", "삭제"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"어음번호: E2E_TEST_어음",
|
||||
"금액: 1,000,000",
|
||||
"만기일: 2026-03-15",
|
||||
"발행처: 테스트발행처"
|
||||
],
|
||||
"expected": "입력한 데이터와 일치"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 모드 진입",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('수정')",
|
||||
"expected": {
|
||||
"url_contains": "mode=edit",
|
||||
"fields_editable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 메모 수정",
|
||||
"action": "click_if_exists",
|
||||
"target": "textarea[name*='memo'], input[placeholder*='메모']",
|
||||
"value": "E2E 수정된 어음 메모_{timestamp}",
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 필수 검증 #2: 수정 저장",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('저장')",
|
||||
"verify": {
|
||||
"url_maintained": true,
|
||||
"no_error_page": true,
|
||||
"api_call": "PUT /api/v1/bills/",
|
||||
"toast": "수정|완료|성공"
|
||||
},
|
||||
"expected": "수정 완료"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"메모: E2E 수정된 어음"
|
||||
],
|
||||
"expected": "수정된 데이터 반영"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 삭제 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('삭제')",
|
||||
"expected": {
|
||||
"confirm_dialog": true,
|
||||
"dialog_message": "삭제|정말"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 필수 검증 #6: 삭제 확인",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('확인'), button:has-text('삭제')",
|
||||
"verify": {
|
||||
"api_call": "DELETE /api/v1/bills/",
|
||||
"toast": "삭제|완료|성공",
|
||||
"redirect": "/accounting/bills"
|
||||
},
|
||||
"expected": "삭제 완료 및 목록 복귀"
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 삭제 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"search": "E2E 수정된 어음",
|
||||
"expected": {
|
||||
"row_exists": false,
|
||||
"message": "테스트 어음이 목록에서 제거됨"
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/bills",
|
||||
"description": "어음 목록 조회"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"endpoint": "/api/v1/bills",
|
||||
"description": "어음 등록"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/bills/{id}",
|
||||
"description": "어음 상세 조회"
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"endpoint": "/api/v1/bills/{id}",
|
||||
"description": "어음 수정"
|
||||
},
|
||||
{
|
||||
"method": "DELETE",
|
||||
"endpoint": "/api/v1/bills/{id}",
|
||||
"description": "어음 삭제"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 2,
|
||||
"name": "등록/저장 버튼",
|
||||
"steps": [7, 13],
|
||||
"criteria": "API 호출 + 성공 토스트 + 데이터 반영"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"criteria": "어음 목록, 등록 버튼, 필터 존재"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "삭제 기능",
|
||||
"steps": [15, 16, 17],
|
||||
"criteria": "DELETE API + 목록에서 제거"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"onCreateFail": "모달 닫기",
|
||||
"onUpdateFail": "테스트 어음 수동 삭제 필요",
|
||||
"onDeleteFail": "테스트 어음 수동 삭제 필요",
|
||||
"cleanupRequired": "E2E_TEST_ 접두사 어음은 테스트 데이터"
|
||||
}
|
||||
}
|
||||
196
_backup_before_enhance/accounting-card-history.json
Normal file
196
_backup_before_enhance/accounting-card-history.json
Normal file
@@ -0,0 +1,196 @@
|
||||
{
|
||||
"id": "accounting-card-history",
|
||||
"name": "카드내역조회 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "회계관리 > 카드내역조회 메뉴의 카드 사용내역 조회/필터/엑셀 기능 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "회계관리",
|
||||
"level2": "카드내역조회",
|
||||
"expectedUrl": "/accounting/card-transactions",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 회계관리 > 카드내역조회",
|
||||
"action": "menu_navigate",
|
||||
"level1": "회계관리",
|
||||
"level2": "카드내역조회",
|
||||
"expected": {
|
||||
"url_contains": "/accounting",
|
||||
"visible": ["카드", "내역"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"카드 사용내역 목록 표시",
|
||||
"카드 선택 가능",
|
||||
"기간 필터 존재"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "카드내역 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
"사용일 컬럼",
|
||||
"카드명 컬럼",
|
||||
"가맹점 컬럼",
|
||||
"금액 컬럼",
|
||||
"승인번호 컬럼"
|
||||
],
|
||||
"expected": "카드내역 테이블 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "카드 선택 드롭다운 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"카드 선택 가능"
|
||||
],
|
||||
"expected": "카드 선택 가능"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 기간 필터 - 시작일",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[type='date']:first-of-type, [class*='datepicker']:first-of-type",
|
||||
"expected": "날짜 선택 열림"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 기간 필터 적용",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('조회'), button:has-text('검색'), button:has-text('적용')",
|
||||
"expected": "필터 적용됨"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 필터 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"필터된 데이터 표시 또는 결과 없음"
|
||||
],
|
||||
"expected": "필터 동작 확인"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 카드 사용내역 상세 보기",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:first-child",
|
||||
"expected": {
|
||||
"detail_view": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"사용일시 표시",
|
||||
"가맹점 정보 표시",
|
||||
"금액 표시",
|
||||
"승인번호 표시"
|
||||
],
|
||||
"expected": "카드 사용 상세 정보 표시"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "목록으로 돌아가기",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('목록'), a:has-text('목록'), [class*='back']",
|
||||
"expected": "목록 페이지로 복귀"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "사용금액 합계 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"합계 금액 표시"
|
||||
],
|
||||
"expected": "사용금액 합계 표시"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "카드별 사용 현황 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"카드별 사용 현황 또는 통계"
|
||||
],
|
||||
"expected": "카드별 현황 표시"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"name": "엑셀 다운로드 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"엑셀 다운로드 버튼 존재"
|
||||
],
|
||||
"expected": "엑셀 다운로드 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"name": "인쇄 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"인쇄 버튼 존재"
|
||||
],
|
||||
"expected": "인쇄 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"name": "페이지네이션 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"페이지 번호 표시"
|
||||
],
|
||||
"expected": "페이지네이션 표시"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/accounting/card-transactions",
|
||||
"description": "카드 사용내역 조회"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/accounting/cards",
|
||||
"description": "카드 목록 조회"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 3,
|
||||
"name": "검색/필터",
|
||||
"steps": [5, 6, 7],
|
||||
"criteria": "기간 필터 동작"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"criteria": "카드내역 목록, 카드 선택, 기간 필터 존재"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"note": "조회 전용 페이지로 데이터 변경 없음"
|
||||
}
|
||||
}
|
||||
283
_backup_before_enhance/accounting-client.json
Normal file
283
_backup_before_enhance/accounting-client.json
Normal file
@@ -0,0 +1,283 @@
|
||||
{
|
||||
"id": "accounting-client",
|
||||
"name": "회계거래처관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": [
|
||||
"error",
|
||||
"fail",
|
||||
"timeout",
|
||||
"404",
|
||||
"500",
|
||||
"blocked"
|
||||
]
|
||||
},
|
||||
"description": "회계관리 > 거래처관리 메뉴의 거래처 CRUD 기능 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "회계관리",
|
||||
"level2": "거래처관리",
|
||||
"expectedUrl": "/accounting/vendors",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"testData": {
|
||||
"create": {
|
||||
"vendorName": "E2E_TEST_회계거래처_{timestamp}",
|
||||
"vendorType": "매출",
|
||||
"creditGrade": "A"
|
||||
}
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 회계관리 > 거래처관리",
|
||||
"action": "menu_navigate",
|
||||
"level1": "회계관리",
|
||||
"level2": "거래처관리",
|
||||
"expected": {
|
||||
"url_contains": "/accounting/vendors",
|
||||
"visible": [
|
||||
"거래처관리",
|
||||
"거래처"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"거래처 목록 표시",
|
||||
"거래처 등록 버튼 존재",
|
||||
"검색 기능 존재"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"전체 거래처 카드",
|
||||
"매출 거래처 카드",
|
||||
"매입 거래처 카드"
|
||||
],
|
||||
"expected": "통계 카드 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "거래처 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
"구분 컬럼",
|
||||
"거래처명 컬럼",
|
||||
"신용등급 컬럼",
|
||||
"거래등급 컬럼",
|
||||
"사업자등록번호 컬럼"
|
||||
],
|
||||
"expected": "거래처 테이블 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 거래처 등록 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('등록'), button:has-text('추가'), button:has-text('신규')",
|
||||
"expected": {
|
||||
"modal_open": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 거래처명 입력",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[name*='name'], input[placeholder*='거래처명']",
|
||||
"value": "E2E_TEST_회계거래처_{timestamp}",
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 거래처 구분 선택",
|
||||
"action": "click_if_exists",
|
||||
"target": "select[name*='type'], button:has-text('매출')",
|
||||
"expected": "거래처 구분 선택"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 필수 검증 #2: 거래처 저장",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('저장'), button:has-text('등록'), button:has-text('확인')",
|
||||
"verify": {
|
||||
"url_maintained": true,
|
||||
"no_error_page": true,
|
||||
"api_call": "POST /api/v1/accounting/vendors",
|
||||
"toast": "등록|저장|완료|성공"
|
||||
},
|
||||
"expected": "거래처 등록 완료"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 등록된 거래처 검색",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[type='search'], input[placeholder*='검색']",
|
||||
"value": "E2E_TEST_회계거래처",
|
||||
"submit": true
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 등록된 거래처 목록 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"E2E_TEST_회계거래처 목록에 표시"
|
||||
],
|
||||
"expected": "등록된 거래처 확인"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 거래처 상세 조회",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:has-text('E2E_TEST_회계거래처')",
|
||||
"expected": {
|
||||
"detail_view": true,
|
||||
"url_change": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "상세 페이지 정보 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"거래처명 표시",
|
||||
"사업자등록번호 표시",
|
||||
"연락처 정보"
|
||||
],
|
||||
"expected": "상세 정보 표시"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 모드 진입",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('수정'), button:has-text('편집')",
|
||||
"expected": {
|
||||
"edit_mode": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 거래처 정보 수정",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[name*='name'], input[placeholder*='거래처명']",
|
||||
"value": "E2E_TEST_회계거래처_수정",
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 거래처 저장",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('저장'), button:has-text('확인')",
|
||||
"verify": {
|
||||
"api_call": "PUT /api/v1/accounting/vendors",
|
||||
"toast": "수정|저장|완료|성공"
|
||||
},
|
||||
"expected": "거래처 수정 완료"
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 거래처 삭제",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('삭제'), button:has-text('제거')",
|
||||
"expected": {
|
||||
"confirm_dialog": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 삭제 확인",
|
||||
"action": "click_if_exists",
|
||||
"target": "[role='alertdialog'] button:has-text('확인'), [role='dialog'] button:has-text('삭제')",
|
||||
"verify": {
|
||||
"api_call": "DELETE /api/v1/accounting/vendors",
|
||||
"toast": "삭제|제거|완료|성공"
|
||||
},
|
||||
"expected": "거래처 삭제 완료"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 삭제 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"E2E_TEST_회계거래처 목록에서 제거"
|
||||
],
|
||||
"expected": "거래처 삭제 반영"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/accounting/vendors",
|
||||
"description": "거래처 목록 조회"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"endpoint": "/api/v1/accounting/vendors",
|
||||
"description": "거래처 등록"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/accounting/vendors/:id",
|
||||
"description": "거래처 상세 조회"
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"endpoint": "/api/v1/accounting/vendors/:id",
|
||||
"description": "거래처 수정"
|
||||
},
|
||||
{
|
||||
"method": "DELETE",
|
||||
"endpoint": "/api/v1/accounting/vendors/:id",
|
||||
"description": "거래처 삭제"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 2,
|
||||
"name": "저장 버튼",
|
||||
"steps": [
|
||||
8,
|
||||
15
|
||||
],
|
||||
"criteria": "API 호출 + 성공 토스트 + 데이터 반영"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [
|
||||
2
|
||||
],
|
||||
"criteria": "거래처 목록, 등록 버튼, 검색 기능 존재"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"onCreateFail": "등록 모달 닫고 재시도",
|
||||
"onUpdateFail": "페이지 새로고침 후 재시도",
|
||||
"onDeleteFail": "수동 삭제 필요",
|
||||
"cleanupRequired": "E2E_TEST_회계거래처* 패턴 데이터 삭제"
|
||||
}
|
||||
}
|
||||
302
_backup_before_enhance/accounting-deposit.json
Normal file
302
_backup_before_enhance/accounting-deposit.json
Normal file
@@ -0,0 +1,302 @@
|
||||
{
|
||||
"id": "accounting-deposit",
|
||||
"name": "입금관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "회계관리 > 입금관리 메뉴의 입금 조회/등록/수정/삭제 전체 CRUD 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "회계관리",
|
||||
"level2": "입금관리",
|
||||
"expectedUrl": "/accounting/deposits",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"testData": {
|
||||
"create": {
|
||||
"vendorName": "E2E_TEST_입금거래처",
|
||||
"amount": "100000",
|
||||
"depositMethod": "계좌이체",
|
||||
"memo": "E2E 자동화 테스트 입금"
|
||||
},
|
||||
"update": {
|
||||
"amount": "150000",
|
||||
"memo": "E2E 수정된 입금 메모"
|
||||
}
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 회계관리 > 입금관리",
|
||||
"action": "menu_navigate",
|
||||
"level1": "회계관리",
|
||||
"level2": "입금관리",
|
||||
"expected": {
|
||||
"url_contains": "/accounting/deposits",
|
||||
"visible": ["입금관리", "입금"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"입금 목록 표시",
|
||||
"입금 등록 버튼 존재",
|
||||
"검색/필터 기능 존재"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "입금 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
"입금일 컬럼",
|
||||
"거래처 컬럼",
|
||||
"금액 컬럼",
|
||||
"입금방법 컬럼",
|
||||
"상태 컬럼"
|
||||
],
|
||||
"expected": "입금 테이블 컬럼 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "검색 기능 테스트",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[placeholder*='검색']",
|
||||
"value": "테스트",
|
||||
"expected": {
|
||||
"data_filtered": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 입금 등록 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('등록'), button:has-text('입금 등록'), button:has-text('추가')",
|
||||
"expected": {
|
||||
"modal": true,
|
||||
"modalTitle": "입금 등록"
|
||||
}
|
||||
},
|
||||
{
|
||||
"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": "number", "value": "100000"},
|
||||
{"name": "입금방법", "type": "select", "value": "계좌이체"},
|
||||
{"name": "메모", "type": "text", "value": "E2E 자동화 테스트 입금_{timestamp}"}
|
||||
],
|
||||
"note": "타임스탬프로 고유성 보장"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 필수 검증 #2: 등록 저장",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('저장'), button:has-text('등록')",
|
||||
"verify": {
|
||||
"url_maintained": true,
|
||||
"no_error_page": true,
|
||||
"api_call": "POST /api/v1/deposits",
|
||||
"toast": "등록|완료|성공"
|
||||
},
|
||||
"expected": "입금 등록 완료"
|
||||
},
|
||||
{
|
||||
"id": "7-modal-close",
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 모달 닫기 확인",
|
||||
"action": "close_modal_if_open",
|
||||
"expected": "모달 닫힘"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 등록 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"search": "E2E 자동화 테스트 입금",
|
||||
"expected": {
|
||||
"row_exists": true,
|
||||
"contains": ["E2E", "100,000"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 입금 상세 페이지 진입",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:has-text('E2E')",
|
||||
"expected": {
|
||||
"url_contains": "/accounting/deposits/",
|
||||
"visible": ["입금 상세", "수정", "삭제"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"금액: 100,000",
|
||||
"입금방법: 계좌이체",
|
||||
"메모: E2E 자동화 테스트"
|
||||
],
|
||||
"expected": "입력한 데이터와 일치"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 모드 진입",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('수정')",
|
||||
"expected": {
|
||||
"url_contains": "mode=edit",
|
||||
"fields_editable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 금액 수정",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[name*='amount'], input[placeholder*='금액']",
|
||||
"value": "150000",
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 메모 수정",
|
||||
"action": "click_if_exists",
|
||||
"target": "textarea[name*='memo'], input[placeholder*='메모']",
|
||||
"value": "E2E 수정된 입금 메모_{timestamp}",
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 필수 검증 #2: 수정 저장",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('저장')",
|
||||
"verify": {
|
||||
"url_maintained": true,
|
||||
"no_error_page": true,
|
||||
"api_call": "PUT /api/v1/deposits/",
|
||||
"toast": "수정|완료|성공"
|
||||
},
|
||||
"expected": "수정 완료"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"금액: 150,000",
|
||||
"메모: E2E 수정된 입금"
|
||||
],
|
||||
"expected": "수정된 데이터 반영"
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 삭제 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('삭제')",
|
||||
"expected": {
|
||||
"confirm_dialog": true,
|
||||
"dialog_message": "삭제|정말"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 필수 검증 #6: 삭제 확인",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('확인'), button:has-text('삭제')",
|
||||
"verify": {
|
||||
"api_call": "DELETE /api/v1/deposits/",
|
||||
"toast": "삭제|완료|성공",
|
||||
"redirect": "/accounting/deposits"
|
||||
},
|
||||
"expected": "삭제 완료 및 목록 복귀"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 삭제 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"search": "E2E 수정된 입금",
|
||||
"expected": {
|
||||
"row_exists": false,
|
||||
"message": "테스트 데이터가 목록에서 제거됨"
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/deposits",
|
||||
"description": "입금 목록 조회"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"endpoint": "/api/v1/deposits",
|
||||
"description": "입금 등록"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/deposits/{id}",
|
||||
"description": "입금 상세 조회"
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"endpoint": "/api/v1/deposits/{id}",
|
||||
"description": "입금 수정"
|
||||
},
|
||||
{
|
||||
"method": "DELETE",
|
||||
"endpoint": "/api/v1/deposits/{id}",
|
||||
"description": "입금 삭제"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 2,
|
||||
"name": "등록/저장 버튼",
|
||||
"steps": [7, 14],
|
||||
"criteria": "API 호출 + 성공 토스트 + 데이터 반영"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"criteria": "입금 목록, 등록 버튼, 필터 존재"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "삭제 기능",
|
||||
"steps": [16, 17, 18],
|
||||
"criteria": "DELETE API + 목록에서 제거"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"onCreateFail": "모달 닫기 → 다음 테스트 영향 없음",
|
||||
"onUpdateFail": "테스트 데이터 수동 삭제 필요",
|
||||
"onDeleteFail": "테스트 데이터 수동 삭제 필요",
|
||||
"cleanupRequired": "E2E_TEST_ 접두사 데이터는 테스트 데이터"
|
||||
}
|
||||
}
|
||||
193
_backup_before_enhance/accounting-expense-forecast.json
Normal file
193
_backup_before_enhance/accounting-expense-forecast.json
Normal file
@@ -0,0 +1,193 @@
|
||||
{
|
||||
"id": "accounting-expense-forecast",
|
||||
"name": "지출예상내역서 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "회계관리 > 지출예상내역서 메뉴의 지출 예상 조회/필터/인쇄 기능 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "회계관리",
|
||||
"level2": "지출예상내역서",
|
||||
"expectedUrl": "/accounting/expected-expenses",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 회계관리 > 지출예상내역서",
|
||||
"action": "menu_navigate",
|
||||
"level1": "회계관리",
|
||||
"level2": "지출예상내역서",
|
||||
"expected": {
|
||||
"url_contains": "/accounting",
|
||||
"visible": ["지출", "예상"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"지출 예상 내역 표시",
|
||||
"기간 선택 가능",
|
||||
"합계 금액 표시"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "지출예상 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
"지출 항목 컬럼",
|
||||
"예상일 컬럼",
|
||||
"금액 컬럼",
|
||||
"비고 컬럼"
|
||||
],
|
||||
"expected": "지출예상 테이블 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "기간 선택 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"기간 선택 가능 (월/주/일)"
|
||||
],
|
||||
"expected": "기간 선택 가능"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 월 선택",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[type='month'], select[name*='month'], [class*='month-picker']",
|
||||
"expected": "월 선택 열림"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 조회 적용",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('조회'), button:has-text('검색'), button:has-text('적용')",
|
||||
"expected": "필터 적용됨"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 필터 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"선택한 기간의 지출 예상 표시"
|
||||
],
|
||||
"expected": "필터 동작 확인"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "지출 카테고리별 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"카테고리별 지출 예상 표시"
|
||||
],
|
||||
"expected": "카테고리별 지출 표시"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "합계 금액 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"총 지출 예상 금액 표시"
|
||||
],
|
||||
"expected": "합계 금액 표시"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "일별 지출 예상 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"일별 지출 예상 캘린더 또는 리스트"
|
||||
],
|
||||
"expected": "일별 지출 표시"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "주요 지출 항목 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"주요 지출 항목 하이라이트"
|
||||
],
|
||||
"expected": "주요 항목 표시"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "인쇄 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"인쇄 버튼 존재"
|
||||
],
|
||||
"expected": "인쇄 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"name": "엑셀 다운로드 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"엑셀 다운로드 버튼 존재"
|
||||
],
|
||||
"expected": "엑셀 다운로드 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"name": "PDF 내보내기 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"PDF 내보내기 버튼 존재"
|
||||
],
|
||||
"expected": "PDF 내보내기 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"name": "이전/다음 기간 네비게이션",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"이전/다음 기간 이동 가능"
|
||||
],
|
||||
"expected": "기간 네비게이션 표시"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/accounting/expected-expenses",
|
||||
"description": "지출예상 목록 조회"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/accounting/expected-expenses/summary",
|
||||
"description": "지출예상 요약 조회"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 3,
|
||||
"name": "검색/필터",
|
||||
"steps": [5, 6, 7],
|
||||
"criteria": "기간 필터 동작"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"criteria": "지출예상 목록, 기간 선택, 합계 표시 존재"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"note": "조회 전용 페이지로 데이터 변경 없음"
|
||||
}
|
||||
}
|
||||
211
_backup_before_enhance/accounting-payment.json
Normal file
211
_backup_before_enhance/accounting-payment.json
Normal file
@@ -0,0 +1,211 @@
|
||||
{
|
||||
"id": "accounting-payment",
|
||||
"name": "결제내역 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "회계관리 > 결제내역 메뉴의 결제 내역 조회/필터/검색/다운로드 기능 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "회계관리",
|
||||
"level2": "결제내역",
|
||||
"expectedUrl": "/payment-history",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 회계관리 > 결제내역",
|
||||
"action": "menu_navigate",
|
||||
"level1": "회계관리",
|
||||
"level2": "결제내역",
|
||||
"expected": {
|
||||
"url_contains": "/payment",
|
||||
"visible": ["결제내역", "결제"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"결제 내역 목록 표시",
|
||||
"기간 필터 존재",
|
||||
"검색 기능 존재"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "결제내역 페이지 구조 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"시작일 선택",
|
||||
"종료일 선택",
|
||||
"결제방법 필터",
|
||||
"조회 버튼"
|
||||
],
|
||||
"expected": "결제내역 조회 폼 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 기간 필터 - 시작일",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[type='date']:first-of-type, input[name*='start']",
|
||||
"value": "2025-01-01",
|
||||
"expected": "시작일 입력"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 기간 필터 - 종료일",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[type='date']:last-of-type, input[name*='end']",
|
||||
"value": "2025-12-31",
|
||||
"expected": "종료일 입력"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 조회 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('조회'), button:has-text('검색')",
|
||||
"expected": {
|
||||
"data_loaded": true,
|
||||
"api_call": "GET /api/v1/payments"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 결제 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
"결제일 컬럼 표시",
|
||||
"결제금액 컬럼 표시",
|
||||
"결제방법 컬럼 표시",
|
||||
"상태 컬럼 표시"
|
||||
],
|
||||
"expected": "결제 테이블 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 결제 데이터 표시 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"테이블에 데이터 행 존재 또는 '데이터 없음' 메시지",
|
||||
"금액 포맷 정상"
|
||||
],
|
||||
"expected": "결제 데이터 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 결제방법 필터 테스트",
|
||||
"action": "click_if_exists",
|
||||
"target": "select[name*='method'], button:has-text('결제방법'), [class*='filter']:has-text('방법')",
|
||||
"expected": "결제방법 필터 옵션 표시"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 상태 필터 테스트",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"완료/취소/대기 등 상태 필터 가능"
|
||||
],
|
||||
"expected": "상태 필터 기능 확인"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 결제 상세 조회",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:first-child, [class*='list'] [class*='item']:first-child",
|
||||
"expected": {
|
||||
"detail_view": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "결제 상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"결제일시 상세",
|
||||
"결제금액 상세",
|
||||
"결제방법 상세",
|
||||
"거래번호/승인번호"
|
||||
],
|
||||
"expected": "결제 상세 정보 표시"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"name": "목록으로 돌아가기",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('목록'), button:has-text('뒤로'), [class*='back']",
|
||||
"expected": "목록 페이지로 복귀"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"name": "필수 검증 #1: 엑셀 다운로드",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('엑셀'), button:has-text('Excel'), button:has-text('다운로드')",
|
||||
"verify": {
|
||||
"api_call": "GET /api/v1/payments/export",
|
||||
"file_download": true
|
||||
},
|
||||
"expected": "엑셀 파일 다운로드"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"name": "합계 금액 표시 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"총 결제금액 합계 표시"
|
||||
],
|
||||
"expected": "합계 영역 표시"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/payments",
|
||||
"description": "결제내역 목록 조회"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/payments/:id",
|
||||
"description": "결제 상세 조회"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/payments/export",
|
||||
"description": "결제내역 엑셀 다운로드"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "엑셀 다운로드",
|
||||
"steps": [14],
|
||||
"criteria": "API 호출 + 파일 다운로드"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"criteria": "결제 내역 목록, 기간 필터, 검색 기능 존재"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"note": "조회 전용 페이지로 데이터 변경 없음"
|
||||
}
|
||||
}
|
||||
196
_backup_before_enhance/accounting-purchase.json
Normal file
196
_backup_before_enhance/accounting-purchase.json
Normal file
@@ -0,0 +1,196 @@
|
||||
{
|
||||
"id": "accounting-purchase",
|
||||
"name": "매입관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "회계관리 > 매입관리 메뉴의 매입 조회/필터/엑셀 기능 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "회계관리",
|
||||
"level2": "매입관리",
|
||||
"expectedUrl": "/accounting/purchase-accounting",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 회계관리 > 매입관리",
|
||||
"action": "menu_navigate",
|
||||
"level1": "회계관리",
|
||||
"level2": "매입관리",
|
||||
"expected": {
|
||||
"url_contains": "/accounting",
|
||||
"visible": ["매입관리", "매입"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"매입 목록 표시",
|
||||
"기간 필터 존재",
|
||||
"합계 금액 표시"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "매입 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
"거래일 컬럼",
|
||||
"거래처 컬럼",
|
||||
"품목 컬럼",
|
||||
"금액 컬럼",
|
||||
"부가세 컬럼"
|
||||
],
|
||||
"expected": "매입 테이블 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "매입 통계 카드 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"총 매입액 표시",
|
||||
"당월 매입 표시",
|
||||
"전월 대비 표시"
|
||||
],
|
||||
"expected": "통계 카드 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 기간 필터 - 시작일",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[type='date']:first-of-type, [class*='datepicker']:first-of-type",
|
||||
"expected": "날짜 선택 열림"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 기간 필터 적용",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('조회'), button:has-text('검색'), button:has-text('적용')",
|
||||
"expected": "필터 적용됨"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 필터 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"필터된 매입 데이터 표시 또는 결과 없음"
|
||||
],
|
||||
"expected": "필터 동작 확인"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 거래처별 필터",
|
||||
"action": "click_if_exists",
|
||||
"target": "select[name*='vendor'], button:has-text('거래처')",
|
||||
"expected": "거래처 필터 가능"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 매입 상세 보기",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:first-child",
|
||||
"expected": {
|
||||
"detail_view": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"거래 상세 정보 표시",
|
||||
"품목 정보 표시",
|
||||
"금액 상세 표시"
|
||||
],
|
||||
"expected": "매입 상세 정보 표시"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "목록으로 돌아가기",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('목록'), a:has-text('목록'), [class*='back']",
|
||||
"expected": "목록 페이지로 복귀"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "매입 합계 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"매입 합계 금액 표시"
|
||||
],
|
||||
"expected": "매입 합계 표시"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"name": "엑셀 다운로드 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"엑셀 다운로드 버튼 존재"
|
||||
],
|
||||
"expected": "엑셀 다운로드 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"name": "인쇄 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"인쇄 버튼 존재"
|
||||
],
|
||||
"expected": "인쇄 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"name": "페이지네이션 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"페이지 번호 표시"
|
||||
],
|
||||
"expected": "페이지네이션 표시"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/accounting/purchases",
|
||||
"description": "매입 목록 조회"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/accounting/purchases/summary",
|
||||
"description": "매입 요약 조회"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 3,
|
||||
"name": "검색/필터",
|
||||
"steps": [5, 6, 7, 8],
|
||||
"criteria": "기간 필터 + 거래처 필터 동작"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"criteria": "매입 목록, 기간 필터, 합계 표시 존재"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"note": "조회 전용 페이지로 데이터 변경 없음"
|
||||
}
|
||||
}
|
||||
241
_backup_before_enhance/accounting-receivable.json
Normal file
241
_backup_before_enhance/accounting-receivable.json
Normal file
@@ -0,0 +1,241 @@
|
||||
{
|
||||
"id": "accounting-receivable",
|
||||
"name": "미수금현황 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "회계관리 > 미수금현황 메뉴의 미수금 조회/필터/검색/엑셀 다운로드 기능 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "회계관리",
|
||||
"level2": "미수금현황",
|
||||
"expectedUrl": "/accounting/receivables-status",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"testData": {
|
||||
"filterStartDate": "2026-01-01",
|
||||
"filterEndDate": "2026-02-28",
|
||||
"searchKeyword": "테스트"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 회계관리 > 미수금현황",
|
||||
"action": "menu_navigate",
|
||||
"level1": "회계관리",
|
||||
"level2": "미수금현황",
|
||||
"expected": {
|
||||
"url_contains": "/accounting/receivables",
|
||||
"visible": ["미수금현황", "미수금"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"미수금 목록 표시",
|
||||
"검색/필터 기능 존재",
|
||||
"날짜 선택 가능"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "미수금 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
"거래처 컬럼",
|
||||
"미수금액 컬럼",
|
||||
"매출일 컬럼",
|
||||
"입금예정일 컬럼",
|
||||
"연체일수 컬럼"
|
||||
],
|
||||
"expected": "미수금 테이블 컬럼 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"총 미수금액 표시",
|
||||
"정상 미수금 표시",
|
||||
"연체 미수금 표시"
|
||||
],
|
||||
"expected": "미수금 통계 카드 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 기간 필터 적용",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "input[type='date']:first-of-type, input[placeholder*='시작'], input[name*='start']" },
|
||||
{ "type": "click_if_exists", "target": "input[type='date']:last-of-type, input[placeholder*='종료'], input[name*='end']" },
|
||||
{ "type": "wait", "duration": 500 }
|
||||
],
|
||||
"expected": {
|
||||
"filter_applied": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 필터 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"expected": {
|
||||
"data_filtered": true,
|
||||
"table_updated": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "SEARCH",
|
||||
"name": "[SEARCH] 거래처 검색",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[placeholder*='검색'], input[placeholder*='거래처']",
|
||||
"value": "테스트",
|
||||
"expected": {
|
||||
"data_filtered": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "SEARCH",
|
||||
"name": "[SEARCH] 검색 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"search": "테스트",
|
||||
"expected": {
|
||||
"row_exists": true,
|
||||
"filtered_by_keyword": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 미수금 상세 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:first-child",
|
||||
"expected": {
|
||||
"detail_modal_or_page": true,
|
||||
"visible": ["거래처", "미수금액", "상세"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"거래처명 표시",
|
||||
"미수금액 표시",
|
||||
"매출 내역 표시"
|
||||
],
|
||||
"expected": "미수금 상세 정보 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 목록으로 복귀",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('목록'), button:has-text('목록으로'), button:has-text('닫기'), button:has-text('뒤로')",
|
||||
"expected": {
|
||||
"url_contains": "/accounting/receivables"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"phase": "EXPORT",
|
||||
"name": "[EXPORT] 엑셀 다운로드 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"엑셀 다운로드 버튼 존재"
|
||||
],
|
||||
"expected": "다운로드 기능 존재"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"phase": "EXPORT",
|
||||
"name": "[EXPORT] 필수 검증 #1: 엑셀 다운로드",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('엑셀'), button:has-text('다운로드'), button:has-text('내보내기')",
|
||||
"verify": {
|
||||
"file_download": true,
|
||||
"file_type": "xlsx",
|
||||
"api_call": "GET /api/v1/receivables/export"
|
||||
},
|
||||
"expected": "엑셀 파일 다운로드"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"phase": "SORT",
|
||||
"name": "[SORT] 컬럼 정렬 테스트",
|
||||
"action": "click_if_exists",
|
||||
"target": "th:has-text('미수금액'), th:has-text('미수금'), th:has-text('금액')",
|
||||
"expected": {
|
||||
"sort_applied": true,
|
||||
"data_reordered": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"name": "연체 현황 탭 확인",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('연체'), [role='tab']:has-text('연체')",
|
||||
"expected": {
|
||||
"tab_active": true,
|
||||
"filtered_data": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/receivables",
|
||||
"description": "미수금 목록 조회"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/receivables/summary",
|
||||
"description": "미수금 통계 조회"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/receivables/{id}",
|
||||
"description": "미수금 상세 조회"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/receivables/export",
|
||||
"description": "미수금 엑셀 다운로드"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "파일 다운로드",
|
||||
"steps": [13],
|
||||
"criteria": "엑셀 파일 다운로드 동작"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "검색/필터",
|
||||
"steps": [5, 6, 7, 8],
|
||||
"criteria": "기간 필터 및 검색 기능"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"criteria": "미수금 목록, 필터, 다운로드 버튼 존재"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"note": "미수금현황은 조회 전용 페이지로 CRUD 없음 (데이터 생성/수정/삭제 없음)"
|
||||
}
|
||||
}
|
||||
196
_backup_before_enhance/accounting-sales.json
Normal file
196
_backup_before_enhance/accounting-sales.json
Normal file
@@ -0,0 +1,196 @@
|
||||
{
|
||||
"id": "accounting-sales",
|
||||
"name": "매출관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "회계관리 > 매출관리 메뉴의 매출 조회/필터/엑셀 기능 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "회계관리",
|
||||
"level2": "매출관리",
|
||||
"expectedUrl": "/accounting/sales-accounting",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 회계관리 > 매출관리",
|
||||
"action": "menu_navigate",
|
||||
"level1": "회계관리",
|
||||
"level2": "매출관리",
|
||||
"expected": {
|
||||
"url_contains": "/accounting",
|
||||
"visible": ["매출관리", "매출"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"매출 목록 표시",
|
||||
"기간 필터 존재",
|
||||
"합계 금액 표시"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "매출 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
"거래일 컬럼",
|
||||
"거래처 컬럼",
|
||||
"품목 컬럼",
|
||||
"금액 컬럼",
|
||||
"부가세 컬럼"
|
||||
],
|
||||
"expected": "매출 테이블 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "매출 통계 카드 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"총 매출액 표시",
|
||||
"당월 매출 표시",
|
||||
"전월 대비 표시"
|
||||
],
|
||||
"expected": "통계 카드 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 기간 필터 - 시작일",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[type='date']:first-of-type, [class*='datepicker']:first-of-type",
|
||||
"expected": "날짜 선택 열림"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 기간 필터 적용",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('조회'), button:has-text('검색'), button:has-text('적용')",
|
||||
"expected": "필터 적용됨"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 필터 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"필터된 매출 데이터 표시 또는 결과 없음"
|
||||
],
|
||||
"expected": "필터 동작 확인"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 거래처별 필터",
|
||||
"action": "click_if_exists",
|
||||
"target": "select[name*='vendor'], button:has-text('거래처')",
|
||||
"expected": "거래처 필터 가능"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 매출 상세 보기",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:first-child",
|
||||
"expected": {
|
||||
"detail_view": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"거래 상세 정보 표시",
|
||||
"품목 정보 표시",
|
||||
"금액 상세 표시"
|
||||
],
|
||||
"expected": "매출 상세 정보 표시"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "목록으로 돌아가기",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('목록'), a:has-text('목록'), [class*='back']",
|
||||
"expected": "목록 페이지로 복귀"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "매출 합계 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"매출 합계 금액 표시"
|
||||
],
|
||||
"expected": "매출 합계 표시"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"name": "엑셀 다운로드 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"엑셀 다운로드 버튼 존재"
|
||||
],
|
||||
"expected": "엑셀 다운로드 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"name": "인쇄 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"인쇄 버튼 존재"
|
||||
],
|
||||
"expected": "인쇄 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"name": "페이지네이션 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"페이지 번호 표시"
|
||||
],
|
||||
"expected": "페이지네이션 표시"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/accounting/sales",
|
||||
"description": "매출 목록 조회"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/accounting/sales/summary",
|
||||
"description": "매출 요약 조회"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 3,
|
||||
"name": "검색/필터",
|
||||
"steps": [5, 6, 7, 8],
|
||||
"criteria": "기간 필터 + 거래처 필터 동작"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"criteria": "매출 목록, 기간 필터, 합계 표시 존재"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"note": "조회 전용 페이지로 데이터 변경 없음"
|
||||
}
|
||||
}
|
||||
302
_backup_before_enhance/accounting-withdrawal.json
Normal file
302
_backup_before_enhance/accounting-withdrawal.json
Normal file
@@ -0,0 +1,302 @@
|
||||
{
|
||||
"id": "accounting-withdrawal",
|
||||
"name": "출금관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "회계관리 > 출금관리 메뉴의 출금 조회/등록/수정/삭제 전체 CRUD 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "회계관리",
|
||||
"level2": "출금관리",
|
||||
"expectedUrl": "/accounting/withdrawals",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"testData": {
|
||||
"create": {
|
||||
"vendorName": "E2E_TEST_출금거래처",
|
||||
"amount": "50000",
|
||||
"withdrawalMethod": "계좌이체",
|
||||
"memo": "E2E 자동화 테스트 출금"
|
||||
},
|
||||
"update": {
|
||||
"amount": "75000",
|
||||
"memo": "E2E 수정된 출금 메모"
|
||||
}
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 회계관리 > 출금관리",
|
||||
"action": "menu_navigate",
|
||||
"level1": "회계관리",
|
||||
"level2": "출금관리",
|
||||
"expected": {
|
||||
"url_contains": "/accounting/withdrawals",
|
||||
"visible": ["출금관리", "출금"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"출금 목록 표시",
|
||||
"출금 등록 버튼 존재",
|
||||
"검색/필터 기능 존재"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "출금 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
"출금일 컬럼",
|
||||
"거래처 컬럼",
|
||||
"금액 컬럼",
|
||||
"출금방법 컬럼",
|
||||
"상태 컬럼"
|
||||
],
|
||||
"expected": "출금 테이블 컬럼 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "검색 기능 테스트",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[placeholder*='검색']",
|
||||
"value": "테스트",
|
||||
"expected": {
|
||||
"data_filtered": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 출금 등록 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('등록'), button:has-text('출금 등록'), button:has-text('추가')",
|
||||
"expected": {
|
||||
"modal": true,
|
||||
"modalTitle": "출금 등록"
|
||||
}
|
||||
},
|
||||
{
|
||||
"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": "number", "value": "50000"},
|
||||
{"name": "출금방법", "type": "select", "value": "계좌이체"},
|
||||
{"name": "메모", "type": "text", "value": "E2E 자동화 테스트 출금_{timestamp}"}
|
||||
],
|
||||
"note": "타임스탬프로 고유성 보장"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 필수 검증 #2: 등록 저장",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('저장'), button:has-text('등록')",
|
||||
"verify": {
|
||||
"url_maintained": true,
|
||||
"no_error_page": true,
|
||||
"api_call": "POST /api/v1/withdrawals",
|
||||
"toast": "등록|완료|성공"
|
||||
},
|
||||
"expected": "출금 등록 완료"
|
||||
},
|
||||
{
|
||||
"id": "7-modal-close",
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 모달 닫기 확인",
|
||||
"action": "close_modal_if_open",
|
||||
"expected": "모달 닫힘"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 등록 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"search": "E2E 자동화 테스트 출금",
|
||||
"expected": {
|
||||
"row_exists": true,
|
||||
"contains": ["E2E", "50,000"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 출금 상세 페이지 진입",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:has-text('E2E')",
|
||||
"expected": {
|
||||
"url_contains": "/accounting/withdrawals/",
|
||||
"visible": ["출금 상세", "수정", "삭제"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"금액: 50,000",
|
||||
"출금방법: 계좌이체",
|
||||
"메모: E2E 자동화 테스트"
|
||||
],
|
||||
"expected": "입력한 데이터와 일치"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 모드 진입",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('수정')",
|
||||
"expected": {
|
||||
"url_contains": "mode=edit",
|
||||
"fields_editable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 금액 수정",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[name*='amount'], input[placeholder*='금액']",
|
||||
"value": "75000",
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 메모 수정",
|
||||
"action": "click_if_exists",
|
||||
"target": "textarea[name*='memo'], input[placeholder*='메모']",
|
||||
"value": "E2E 수정된 출금 메모_{timestamp}",
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 필수 검증 #2: 수정 저장",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('저장')",
|
||||
"verify": {
|
||||
"url_maintained": true,
|
||||
"no_error_page": true,
|
||||
"api_call": "PUT /api/v1/withdrawals/",
|
||||
"toast": "수정|완료|성공"
|
||||
},
|
||||
"expected": "수정 완료"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"금액: 75,000",
|
||||
"메모: E2E 수정된 출금"
|
||||
],
|
||||
"expected": "수정된 데이터 반영"
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 삭제 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('삭제')",
|
||||
"expected": {
|
||||
"confirm_dialog": true,
|
||||
"dialog_message": "삭제|정말"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 필수 검증 #6: 삭제 확인",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('확인'), button:has-text('삭제')",
|
||||
"verify": {
|
||||
"api_call": "DELETE /api/v1/withdrawals/",
|
||||
"toast": "삭제|완료|성공",
|
||||
"redirect": "/accounting/withdrawals"
|
||||
},
|
||||
"expected": "삭제 완료 및 목록 복귀"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 삭제 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"search": "E2E 수정된 출금",
|
||||
"expected": {
|
||||
"row_exists": false,
|
||||
"message": "테스트 데이터가 목록에서 제거됨"
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/withdrawals",
|
||||
"description": "출금 목록 조회"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"endpoint": "/api/v1/withdrawals",
|
||||
"description": "출금 등록"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/withdrawals/{id}",
|
||||
"description": "출금 상세 조회"
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"endpoint": "/api/v1/withdrawals/{id}",
|
||||
"description": "출금 수정"
|
||||
},
|
||||
{
|
||||
"method": "DELETE",
|
||||
"endpoint": "/api/v1/withdrawals/{id}",
|
||||
"description": "출금 삭제"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 2,
|
||||
"name": "등록/저장 버튼",
|
||||
"steps": [7, 14],
|
||||
"criteria": "API 호출 + 성공 토스트 + 데이터 반영"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"criteria": "출금 목록, 등록 버튼, 필터 존재"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "삭제 기능",
|
||||
"steps": [16, 17, 18],
|
||||
"criteria": "DELETE API + 목록에서 제거"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"onCreateFail": "모달 닫기 → 다음 테스트 영향 없음",
|
||||
"onUpdateFail": "테스트 데이터 수동 삭제 필요",
|
||||
"onDeleteFail": "테스트 데이터 수동 삭제 필요",
|
||||
"cleanupRequired": "E2E_TEST_ 접두사 데이터는 테스트 데이터"
|
||||
}
|
||||
}
|
||||
679
_backup_before_enhance/approval-box.json
Normal file
679
_backup_before_enhance/approval-box.json
Normal file
@@ -0,0 +1,679 @@
|
||||
{
|
||||
"id": "approval-box",
|
||||
"name": "결재함 E2E 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": [
|
||||
"error",
|
||||
"fail",
|
||||
"timeout",
|
||||
"404",
|
||||
"500",
|
||||
"blocked"
|
||||
]
|
||||
},
|
||||
"description": "결재함 페이지의 전체 기능을 검증합니다 (탭 전환, 검색, 필터, 승인/반려, 모달)",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "결재관리",
|
||||
"level2": "결재함",
|
||||
"expectedUrl": "/ko/approval/inbox",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"navigation": {
|
||||
"targetUrl": "/approval/inbox",
|
||||
"urlPattern": "/approval/inbox|/ko/approval/inbox",
|
||||
"menuHints": [
|
||||
"결재함",
|
||||
"결재 함",
|
||||
"결재관리"
|
||||
]
|
||||
},
|
||||
"menuNavigationEnhanced": {
|
||||
"strategy": "scroll-and-search",
|
||||
"description": "사이드바를 스크롤하며 메뉴를 찾고 클릭하여 404를 방지",
|
||||
"level1": "결재관리",
|
||||
"level2": "결재함",
|
||||
"alternativeLevel2Names": [
|
||||
"결재함",
|
||||
"결재 함",
|
||||
"승인함",
|
||||
"Approval Box",
|
||||
"inbox"
|
||||
],
|
||||
"fallbackUrls": [
|
||||
"/ko/approval/inbox",
|
||||
"/ko/approval/box",
|
||||
"/ko/approvals/inbox",
|
||||
"/ko/approval-management/inbox",
|
||||
"/approval/inbox"
|
||||
],
|
||||
"scrollConfig": {
|
||||
"sidebarSelector": "nav, aside, [role='navigation'], .sidebar, #sidebar",
|
||||
"menuItemSelector": "a, button, [role='menuitem'], [role='treeitem']",
|
||||
"scrollStep": 200,
|
||||
"maxScrollAttempts": 10,
|
||||
"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
|
||||
}
|
||||
],
|
||||
"verification": [
|
||||
"사이드바가 화면에 보이는지 확인",
|
||||
"모든 메뉴가 펼쳐졌는지 확인"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"name": "1차 메뉴 찾기: 결재관리 (스크롤 포함)",
|
||||
"description": "사이드바를 스크롤하며 '결재관리' 메뉴를 찾아 클릭",
|
||||
"actions": [
|
||||
{
|
||||
"type": "scrollAndFind",
|
||||
"target": "결재관리",
|
||||
"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"
|
||||
}
|
||||
],
|
||||
"verification": [
|
||||
"결재관리 메뉴가 클릭되었는지 확인",
|
||||
"서브메뉴가 펼쳐졌는지 확인",
|
||||
"하위 메뉴 항목들이 보이는지 확인"
|
||||
],
|
||||
"fallback": {
|
||||
"if": "메뉴를 찾을 수 없음",
|
||||
"then": "사이드바 전체를 스크롤하며 재탐색"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "2차 메뉴 찾기: 결재함 (스크롤 포함)",
|
||||
"description": "서브메뉴에서 '결재함'을 찾아 클릭",
|
||||
"actions": [
|
||||
{
|
||||
"type": "scrollAndFind",
|
||||
"target": "결재함",
|
||||
"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"
|
||||
}
|
||||
],
|
||||
"verification": [
|
||||
"결재함 메뉴 클릭 성공",
|
||||
"페이지 이동 또는 컨텐츠 로드"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "404 에러 감지 및 대체 경로 시도",
|
||||
"description": "페이지 로드 후 404 에러 여부 확인, 404시 대체 경로 탐색",
|
||||
"actions": [
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 1000
|
||||
},
|
||||
{
|
||||
"type": "checkFor404",
|
||||
"indicators": [
|
||||
"페이지를 찾을 수 없습니다",
|
||||
"404",
|
||||
"Not Found",
|
||||
"존재하지 않거나"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "screenshot",
|
||||
"name": "page_load_result"
|
||||
}
|
||||
],
|
||||
"verification": [
|
||||
"현재 페이지가 404인지 확인"
|
||||
],
|
||||
"onError404": {
|
||||
"description": "404 에러 발생 시 대체 URL 시도",
|
||||
"actions": [
|
||||
{
|
||||
"type": "log",
|
||||
"message": "404 감지 - 대체 경로 탐색 시작"
|
||||
},
|
||||
{
|
||||
"type": "tryAlternativeUrls",
|
||||
"urls": [
|
||||
"/ko/approval/inbox",
|
||||
"/ko/approvals/inbox",
|
||||
"/ko/approval-box"
|
||||
],
|
||||
"stopOnSuccess": true
|
||||
},
|
||||
{
|
||||
"type": "ifStillFailed",
|
||||
"action": "navigateViaMenuClick",
|
||||
"description": "URL 직접 접근 실패 시 메뉴 클릭으로 재시도"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "페이지 정상 로드 확인",
|
||||
"description": "결재함 페이지가 정상적으로 로드되었는지 확인",
|
||||
"actions": [
|
||||
{
|
||||
"type": "verify",
|
||||
"target": "pageTitle",
|
||||
"contains": [
|
||||
"결재함",
|
||||
"결재",
|
||||
"Approval"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "verify",
|
||||
"target": "pageContent",
|
||||
"notContains": [
|
||||
"404",
|
||||
"찾을 수 없습니다",
|
||||
"Not Found"
|
||||
]
|
||||
}
|
||||
],
|
||||
"verification": [
|
||||
"페이지 제목 '결재함' 또는 관련 텍스트 표시",
|
||||
"404 에러 메시지 미표시",
|
||||
"콘텐츠가 정상 렌더링됨"
|
||||
],
|
||||
"successCriteria": {
|
||||
"urlPattern": "/approval",
|
||||
"requiredElements": [
|
||||
"결재",
|
||||
"문서",
|
||||
"승인"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "verify_element",
|
||||
"target": "[class*='card'], [class*='stat']",
|
||||
"verification": [
|
||||
"전체결재 건수 기록",
|
||||
"미결재 건수 기록",
|
||||
"결재완료 건수 기록",
|
||||
"결재반려 건수 기록"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "탭 구조 확인",
|
||||
"action": "verify_element",
|
||||
"target": "[role='tab'], button[role='tab']",
|
||||
"verification": [
|
||||
"'전체결재' 탭 존재 확인",
|
||||
"'미결재' 탭 존재 확인",
|
||||
"'결재완료' 탭 존재 확인",
|
||||
"'결재반려' 탭 존재 확인"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "테이블 데이터 확인",
|
||||
"action": "verify_table",
|
||||
"target": "table",
|
||||
"verification": [
|
||||
"테이블 헤더 컬럼 확인",
|
||||
"데이터 행 존재 여부 확인",
|
||||
"페이지네이션 표시 확인"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "⚠️ 필수 검증: 결재 문서 상세 보기",
|
||||
"description": "테이블에서 결재 문서 클릭하여 상세 모달/페이지 확인",
|
||||
"actions": [
|
||||
{
|
||||
"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",
|
||||
"인쇄"
|
||||
]
|
||||
},
|
||||
"note": "결재 문서가 없으면 데이터 생성 또는 SKIP"
|
||||
},
|
||||
{
|
||||
"id": "8-pdf-1",
|
||||
"name": "⚠️ 필수 검증: PDF 다운로드 전 모달 스크린샷",
|
||||
"description": "PDF 생성 전 모달 상태를 스크린샷으로 캡처하여 CSS 문제 감지용 기준 이미지 확보",
|
||||
"prerequisite": "step-8의 문서 상세 모달이 열려있는 상태에서 실행",
|
||||
"actions": [
|
||||
{
|
||||
"type": "screenshot",
|
||||
"name": "pdf-preview-before-download-approval-box",
|
||||
"fullPage": false,
|
||||
"selector": "[role='dialog'], .modal, [data-state='open']",
|
||||
"savePath": "tests/e2e/results/hotfix/screenshots/",
|
||||
"description": "PDF 생성 대상 모달 전체 캡처"
|
||||
}
|
||||
],
|
||||
"verify": {
|
||||
"screenshotCaptured": true,
|
||||
"purpose": "PDF CSS 문제 감지를 위한 기준 이미지"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "8-pdf-2",
|
||||
"name": "⚠️ 필수 검증: PDF 다운로드 실행 및 파일 보관",
|
||||
"description": "PDF 다운로드 후 파일을 지정 폴더에 보관하여 수동 검증 가능하게 함",
|
||||
"actions": [
|
||||
{
|
||||
"type": "verify",
|
||||
"target": "PDF 버튼 존재",
|
||||
"selector": "button:has-text('PDF'), [aria-label*='PDF']",
|
||||
"description": "PDF 다운로드 버튼 존재 확인"
|
||||
},
|
||||
{
|
||||
"type": "expectResponse",
|
||||
"id": "pdf-download-response-approval-box",
|
||||
"urlPattern": "/api/v1/approvals/*/pdf",
|
||||
"description": "PDF 다운로드 API 응답 대기 설정"
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "PDF 버튼",
|
||||
"selector": "button:has-text('PDF')",
|
||||
"description": "PDF 다운로드 버튼 클릭"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 3000,
|
||||
"description": "PDF 생성 및 다운로드 대기"
|
||||
},
|
||||
{
|
||||
"type": "assertResponse",
|
||||
"id": "pdf-download-response-approval-box",
|
||||
"checks": {
|
||||
"status": 200,
|
||||
"contentType": "application/pdf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "saveDownloadedFile",
|
||||
"targetPath": "tests/e2e/results/hotfix/pdf-samples/",
|
||||
"fileNamePattern": "approval-box-{timestamp}.pdf",
|
||||
"description": "다운로드된 PDF 파일을 지정 폴더에 보관"
|
||||
}
|
||||
],
|
||||
"verify": {
|
||||
"apiSuccess": true,
|
||||
"fileDownloaded": true,
|
||||
"fileSaved": "tests/e2e/results/hotfix/pdf-samples/"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "8-pdf-3",
|
||||
"name": "⚠️ PDF 파일 유효성 검증",
|
||||
"description": "다운로드된 PDF 파일의 기본 유효성 검사",
|
||||
"actions": [
|
||||
{
|
||||
"type": "verifyDownloadedFile",
|
||||
"checks": {
|
||||
"fileExists": true,
|
||||
"fileSize": "> 1024",
|
||||
"pdfSignature": "%PDF-",
|
||||
"description": "PDF 파일 헤더 검증"
|
||||
}
|
||||
}
|
||||
],
|
||||
"verify": {
|
||||
"pdfValid": true,
|
||||
"minFileSize": "1KB 이상"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "8-pdf-4",
|
||||
"name": "📋 PDF 스타일 수동 확인 체크리스트",
|
||||
"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": "결재선"
|
||||
}
|
||||
],
|
||||
"outputFiles": {
|
||||
"screenshot": "tests/e2e/results/hotfix/screenshots/pdf-preview-before-download-approval-box-*.png",
|
||||
"pdfFile": "tests/e2e/results/hotfix/pdf-samples/approval-box-*.pdf"
|
||||
},
|
||||
"reportFlag": {
|
||||
"requiresManualReview": true,
|
||||
"message": "⚠️ PDF 스타일 수동 확인 필요 - 위 체크리스트 항목을 PDF 파일에서 직접 확인하세요"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "⚠️ 필수 검증 #4: 결재 승인 실제 수행",
|
||||
"description": "미결재 문서에 대해 실제 승인 처리 수행",
|
||||
"actions": [
|
||||
{
|
||||
"type": "verify",
|
||||
"target": "승인 버튼 존재"
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "승인 버튼",
|
||||
"description": "결재 승인 클릭"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"target": "확인 다이얼로그"
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "확인",
|
||||
"description": "승인 확인"
|
||||
}
|
||||
],
|
||||
"expect": {
|
||||
"urlMaintained": true,
|
||||
"noErrorPage": true,
|
||||
"apiCall": "POST /api/v1/approvals/{id}/approve",
|
||||
"toast": "승인되었습니다",
|
||||
"statusChange": "미결재 → 결재완료"
|
||||
},
|
||||
"note": "⚠️ 버튼 존재만 확인하면 불완전! 실제 승인까지 검증 필수!"
|
||||
},
|
||||
{
|
||||
"id": "9-1",
|
||||
"name": "결재 승인 결과 확인",
|
||||
"description": "승인 후 결재완료 탭에서 해당 문서 확인",
|
||||
"actions": [
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "결재완료 탭"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 500
|
||||
}
|
||||
],
|
||||
"verify": {
|
||||
"documentMoved": "승인한 문서가 결재완료 탭에 표시",
|
||||
"statusUpdated": "결재 상태가 '완료'로 변경"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"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": "click_if_exists",
|
||||
"target": "반려 사유"
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "확인",
|
||||
"description": "반려 확인"
|
||||
}
|
||||
],
|
||||
"expect": {
|
||||
"urlMaintained": true,
|
||||
"noErrorPage": true,
|
||||
"apiCall": "POST /api/v1/approvals/{id}/reject",
|
||||
"toast": "반려되었습니다",
|
||||
"statusChange": "미결재 → 결재반려"
|
||||
},
|
||||
"note": "⚠️ 반려 버튼 존재만 확인하면 불완전! 실제 반려까지 검증 필수!"
|
||||
},
|
||||
{
|
||||
"id": "10-1",
|
||||
"name": "결재 반려 결과 확인",
|
||||
"description": "반려 후 결재반려 탭에서 해당 문서 확인",
|
||||
"actions": [
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "결재반려 탭"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 500
|
||||
}
|
||||
],
|
||||
"verify": {
|
||||
"documentMoved": "반려한 문서가 결재반려 탭에 표시",
|
||||
"statusUpdated": "결재 상태가 '반려'로 변경",
|
||||
"rejectReason": "반려 사유가 표시"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "검색 기능 테스트",
|
||||
"description": "검색 필터로 결재 문서 검색",
|
||||
"actions": [
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "전체결재 탭"
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "검색 입력창"
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "검색 버튼"
|
||||
}
|
||||
],
|
||||
"verify": {
|
||||
"searchApplied": true,
|
||||
"filteredResults": "검색어에 맞는 결과 표시"
|
||||
}
|
||||
}
|
||||
],
|
||||
"mandatoryVerifications": {
|
||||
"description": "E2E_TEST_CONFIG.md 기준 필수 검증 항목",
|
||||
"items": [
|
||||
{
|
||||
"id": 4,
|
||||
"name": "결재 승인/반려 완료",
|
||||
"trigger": "결재 문서 상세의 승인/반려 버튼",
|
||||
"verification": "실제 승인/반려 동작 + API 호출 + 결과 확인",
|
||||
"failCondition": "버튼 존재만 확인, 클릭하지 않음",
|
||||
"steps": [
|
||||
"9",
|
||||
"10"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"expectedAPIs": [
|
||||
"GET /api/v1/approvals/inbox - 결재함 목록 조회",
|
||||
"GET /api/v1/approvals/inbox/summary - 결재함 통계",
|
||||
"GET /api/v1/approvals/{id} - 결재 문서 상세 조회",
|
||||
"POST /api/v1/approvals/{id}/approve - 결재 승인",
|
||||
"POST /api/v1/approvals/{id}/reject - 결재 반려"
|
||||
],
|
||||
"notes": [
|
||||
"⚠️ 404 방지: 반드시 메뉴 클릭으로 페이지 진입 (직접 URL 접근 금지)",
|
||||
"⚠️ 스크롤 필수: 사이드바가 길 경우 메뉴가 화면 밖에 있을 수 있음",
|
||||
"⚠️ 대체 경로: 메뉴명이 변경되었을 수 있으므로 다양한 이름으로 탐색",
|
||||
"메뉴 계층: 결재관리 > 결재함",
|
||||
"탭 전환 시 URL 변경 없이 데이터만 필터링됨"
|
||||
]
|
||||
}
|
||||
461
_backup_before_enhance/attendance-checkin.json
Normal file
461
_backup_before_enhance/attendance-checkin.json
Normal file
@@ -0,0 +1,461 @@
|
||||
{
|
||||
"id": "attendance-checkin",
|
||||
"name": "근태현황 출퇴근 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "위치 정보 권한 허용 후 출근/퇴근 기록을 테스트하는 E2E 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"url": "/hr/attendance",
|
||||
|
||||
"navigation": {
|
||||
"targetUrl": "/hr/attendance",
|
||||
"urlPattern": "/hr/attendance|/ko/hr/attendance",
|
||||
"menuHints": ["근태현황", "근태 현황", "출퇴근", "인사관리"]
|
||||
},
|
||||
"menuNavigation": {
|
||||
"level1": "인사관리",
|
||||
"level2": "근태현황",
|
||||
"expectedUrl": "/hr/attendance",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"menuNavigationEnhanced": {
|
||||
"strategy": "scroll-and-search",
|
||||
"description": "사이드바를 스크롤하며 메뉴를 찾고 클릭하여 404를 방지",
|
||||
"level1": "인사관리",
|
||||
"level2": "근태현황",
|
||||
"alternativeLevel1Names": ["인사관리", "인사 관리", "HR", "Human Resource", "HR관리"],
|
||||
"alternativeLevel2Names": ["근태현황", "근태 현황", "출퇴근", "Attendance", "출퇴근현황", "근태관리"],
|
||||
"fallbackUrls": [
|
||||
"/hr/attendance",
|
||||
"/ko/hr/attendance",
|
||||
"/ko/hr/attendance-status",
|
||||
"/ko/hr/checkin",
|
||||
"/ko/human-resource/attendance"
|
||||
],
|
||||
"scrollConfig": {
|
||||
"sidebarSelector": "nav, aside, [role='navigation'], .sidebar, #sidebar",
|
||||
"menuItemSelector": "a, button, [role='menuitem'], [role='treeitem']",
|
||||
"scrollStep": 200,
|
||||
"maxScrollAttempts": 10,
|
||||
"scrollDelay": 300
|
||||
}
|
||||
},
|
||||
|
||||
"timeout": 120000,
|
||||
"tags": ["hr", "attendance", "geolocation", "checkin", "checkout"],
|
||||
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
|
||||
"browserConfig": {
|
||||
"permissions": {
|
||||
"geolocation": {
|
||||
"grant": true,
|
||||
"description": "위치 정보 접근 권한 허용 - 출퇴근 기록에 필수",
|
||||
"mockLocation": {
|
||||
"enabled": true,
|
||||
"latitude": 37.557358,
|
||||
"longitude": 126.864414,
|
||||
"accuracy": 100
|
||||
}
|
||||
}
|
||||
},
|
||||
"contextOptions": {
|
||||
"geolocation": {
|
||||
"latitude": 37.557358,
|
||||
"longitude": 126.864414
|
||||
},
|
||||
"permissions": ["geolocation"]
|
||||
}
|
||||
},
|
||||
|
||||
"preTestSetup": {
|
||||
"description": "테스트 시작 전 Playwright 브라우저 컨텍스트에서 위치 권한 설정",
|
||||
"playwright": {
|
||||
"grantPermissions": ["geolocation"],
|
||||
"setGeolocation": {
|
||||
"latitude": 37.557358,
|
||||
"longitude": 126.864414,
|
||||
"accuracy": 100
|
||||
},
|
||||
"code": [
|
||||
"// Playwright MCP 사용 시 브라우저 시작 직후 실행",
|
||||
"// mcp__playwright__playwright_evaluate로 위치 권한 자동 허용",
|
||||
"await context.grantPermissions(['geolocation']);",
|
||||
"await context.setGeolocation({ latitude: 37.557358, longitude: 126.864414 });"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
"steps": [
|
||||
{
|
||||
"id": "step-0",
|
||||
"name": "🔐 Geolocation API 모킹 (권한 팝업 방지)",
|
||||
"description": "페이지 로드 직후 Geolocation API를 모킹하여 브라우저 권한 팝업이 나타나지 않도록 함",
|
||||
"executeBeforeNavigation": false,
|
||||
"executeImmediately": true,
|
||||
"actions": [
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "(() => { const mockPosition = { coords: { latitude: 37.557358, longitude: 126.864414, accuracy: 100, altitude: null, altitudeAccuracy: null, heading: null, speed: null }, timestamp: Date.now() }; const mockGeolocation = { getCurrentPosition: (success, error, options) => { console.log('[E2E] Geolocation.getCurrentPosition - 모킹된 위치 반환'); setTimeout(() => success(mockPosition), 50); }, watchPosition: (success, error, options) => { console.log('[E2E] Geolocation.watchPosition - 모킹된 위치 반환'); setTimeout(() => success(mockPosition), 50); return 1; }, clearWatch: (id) => {} }; Object.defineProperty(navigator, 'geolocation', { value: mockGeolocation, writable: false, configurable: true }); console.log('[E2E] Geolocation API 모킹 완료 - 서울 영등포구 좌표'); return { success: true, coords: mockPosition.coords }; })()",
|
||||
"description": "Geolocation API 모킹 (서울 영등포구 좌표: 37.557358, 126.864414)"
|
||||
},
|
||||
{ "type": "wait", "duration": 300, "description": "모킹 적용 대기" }
|
||||
],
|
||||
"note": "Geolocation API를 모킹하면 브라우저가 위치 권한을 요청하지 않음"
|
||||
},
|
||||
{
|
||||
"id": "step-0-1",
|
||||
"name": "🗺️ 브라우저 위치 권한 팝업 클릭 (좌측 상단)",
|
||||
"description": "Chrome 브라우저 좌측 상단에 나타나는 '사이트에 있는 동안 허용' 팝업 클릭",
|
||||
"actions": [
|
||||
{ "type": "wait", "duration": 1500, "description": "위치 권한 팝업 표시 대기" },
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "(async function() { const permissionSelectors = [ '[class*=\"permission\"][class*=\"allow\"]', '[class*=\"infobar\"] button', '[aria-label*=\"허용\"]', '[aria-label*=\"Allow\"]', 'button:has-text(\"사이트에 있는 동안 허용\")', 'button:has-text(\"허용\")', 'button:has-text(\"Allow\")', '[data-testid*=\"permission\"]', '.permission-prompt button', '[class*=\"PermissionPrompt\"] button' ]; for (const sel of permissionSelectors) { try { const btn = document.querySelector(sel); if (btn && btn.offsetParent !== null) { btn.click(); console.log('[E2E] 위치 권한 팝업 클릭 성공:', sel); await new Promise(r => setTimeout(r, 500)); return { clicked: true, selector: sel }; } } catch(e) {} } const allButtons = Array.from(document.querySelectorAll('button, [role=\"button\"]')); const allowBtn = allButtons.find(b => { const text = b.innerText || b.textContent || ''; return text.includes('사이트에 있는 동안 허용') || text.includes('허용') || text.includes('Allow'); }); if (allowBtn && allowBtn.offsetParent !== null) { allowBtn.click(); console.log('[E2E] 위치 권한 팝업 텍스트 검색으로 클릭'); return { clicked: true, method: 'textSearch' }; } console.log('[E2E] 위치 권한 팝업 없음 (이미 허용되었거나 모킹으로 우회됨)'); return { clicked: false, reason: 'no_popup_found' }; })()",
|
||||
"description": "좌측 상단 권한 팝업 찾아서 클릭"
|
||||
},
|
||||
{ "type": "wait", "duration": 500, "description": "권한 설정 적용 대기" }
|
||||
],
|
||||
"errorHandling": {
|
||||
"onTimeout": "continue",
|
||||
"onNotFound": "continue",
|
||||
"reason": "팝업이 없으면 이미 허용된 상태로 간주"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-0-2",
|
||||
"name": "📂 사이드바 메뉴 전체 펼치기",
|
||||
"description": "모두 펼치기 버튼을 클릭하여 전체 메뉴 펼침",
|
||||
"actions": [
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "document.querySelector('.sidebar-scroll')?.scrollTo({top:0,behavior:'instant'})"
|
||||
},
|
||||
{ "type": "wait", "duration": 300 },
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "Array.from(document.querySelectorAll('button')).find(b => b.innerText?.includes('모두 펼치기'))?.click()"
|
||||
},
|
||||
{ "type": "wait", "duration": 2000 },
|
||||
{ "type": "screenshot", "name": "after_permission_grant_and_menu_expanded" }
|
||||
],
|
||||
"verification": [
|
||||
"사이드바 메뉴가 펼쳐졌는지 확인"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "1차 메뉴 찾기: 인사관리 (스크롤 포함)",
|
||||
"description": "사이드바를 스크롤하며 '인사관리' 메뉴를 찾아 클릭",
|
||||
"actions": [
|
||||
{
|
||||
"type": "scrollAndFind",
|
||||
"target": "인사관리",
|
||||
"alternativeTexts": ["인사관리", "인사 관리", "HR", "Human Resource"],
|
||||
"scrollContainer": "sidebar",
|
||||
"maxAttempts": 10,
|
||||
"description": "스크롤하며 인사관리 메뉴 찾기"
|
||||
},
|
||||
{ "type": "wait", "duration": 300 },
|
||||
{ "type": "click_if_exists", "target": "인사관리", "description": "인사관리 메뉴 클릭" },
|
||||
{ "type": "wait", "duration": 500, "description": "서브메뉴 펼쳐지기 대기" },
|
||||
{ "type": "screenshot", "name": "hr_menu_expanded" }
|
||||
],
|
||||
"verification": [
|
||||
"인사관리 메뉴가 클릭되었는지 확인",
|
||||
"서브메뉴가 펼쳐졌는지 확인",
|
||||
"하위 메뉴 항목들이 보이는지 확인"
|
||||
],
|
||||
"fallback": {
|
||||
"if": "메뉴를 찾을 수 없음",
|
||||
"then": "사이드바 전체를 스크롤하며 재탐색"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "2차 메뉴 찾기: 근태현황 (스크롤 포함)",
|
||||
"description": "서브메뉴에서 '근태현황'을 찾아 클릭",
|
||||
"actions": [
|
||||
{
|
||||
"type": "scrollAndFind",
|
||||
"target": "근태현황",
|
||||
"alternativeTexts": ["근태현황", "근태 현황", "출퇴근", "Attendance"],
|
||||
"scrollContainer": "submenu",
|
||||
"maxAttempts": 5,
|
||||
"description": "서브메뉴에서 근태현황 찾기"
|
||||
},
|
||||
{ "type": "wait", "duration": 200 },
|
||||
{ "type": "click_if_exists", "target": "근태현황", "description": "근태현황 메뉴 클릭" },
|
||||
{ "type": "wait", "target": "페이지 로드 완료", "timeout": 10000 },
|
||||
{ "type": "screenshot", "name": "attendance_page" }
|
||||
],
|
||||
"verification": [
|
||||
"근태현황 메뉴 클릭 성공",
|
||||
"페이지 이동 또는 컨텐츠 로드"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "404 에러 감지 및 대체 경로 시도",
|
||||
"description": "페이지 로드 후 404 에러 여부 확인, 404시 대체 경로 탐색",
|
||||
"actions": [
|
||||
{ "type": "wait", "duration": 1000 },
|
||||
{ "type": "checkFor404", "indicators": [
|
||||
"페이지를 찾을 수 없습니다",
|
||||
"404",
|
||||
"Not Found",
|
||||
"존재하지 않거나"
|
||||
]},
|
||||
{ "type": "screenshot", "name": "page_load_result" }
|
||||
],
|
||||
"verification": [
|
||||
"현재 페이지가 404인지 확인"
|
||||
],
|
||||
"onError404": {
|
||||
"description": "404 에러 발생 시 대체 URL 시도",
|
||||
"actions": [
|
||||
{ "type": "log", "message": "404 감지 - 대체 경로 탐색 시작" },
|
||||
{
|
||||
"type": "tryAlternativeUrls",
|
||||
"urls": [
|
||||
"/ko/hr/attendance",
|
||||
"/ko/hr/attendance-status",
|
||||
"/ko/hr/checkin"
|
||||
],
|
||||
"stopOnSuccess": true
|
||||
},
|
||||
{
|
||||
"type": "ifStillFailed",
|
||||
"action": "navigateViaMenuClick",
|
||||
"description": "URL 직접 접근 실패 시 메뉴 클릭으로 재시도"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "페이지 정상 로드 확인",
|
||||
"description": "근태현황 페이지가 정상적으로 로드되었는지 확인",
|
||||
"actions": [
|
||||
{ "type": "verify", "target": "pageTitle", "contains": ["근태현황", "출퇴근", "Attendance"] },
|
||||
{ "type": "verify", "target": "pageContent", "notContains": ["404", "찾을 수 없습니다", "Not Found"] }
|
||||
],
|
||||
"verification": [
|
||||
"페이지 제목 '근태현황' 또는 관련 텍스트 표시",
|
||||
"404 에러 메시지 미표시",
|
||||
"콘텐츠가 정상 렌더링됨"
|
||||
],
|
||||
"successCriteria": {
|
||||
"urlPattern": "/hr/attendance",
|
||||
"requiredElements": ["출퇴근", "출근", "퇴근", "현재 시간"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-5",
|
||||
"name": "브라우저 위치 권한 설정",
|
||||
"description": "Playwright context에서 위치 정보 권한을 허용하고 가상 위치 설정",
|
||||
"playwright": {
|
||||
"code": "await context.grantPermissions(['geolocation']);",
|
||||
"setGeolocation": {
|
||||
"latitude": 37.557358,
|
||||
"longitude": 126.864414
|
||||
}
|
||||
},
|
||||
"expect": {
|
||||
"permissionGranted": "geolocation"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-6",
|
||||
"name": "위치 정보 로딩 대기",
|
||||
"description": "Google Map 로딩 및 현재 위치 표시 대기",
|
||||
"waitFor": {
|
||||
"type": "element",
|
||||
"selector": "region[name='지도']",
|
||||
"timeout": 10000
|
||||
},
|
||||
"expect": {
|
||||
"mapLoaded": true,
|
||||
"locationMarkerVisible": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-7",
|
||||
"name": "사용자 정보 확인",
|
||||
"description": "출퇴근 패널에서 로그인한 사용자 정보 확인",
|
||||
"verify": {
|
||||
"userInfo": {
|
||||
"name": "홍킬동",
|
||||
"department": "부서명 · 개발중인 메뉴"
|
||||
},
|
||||
"currentTime": {
|
||||
"format": "HH:mm:ss",
|
||||
"updating": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-8",
|
||||
"name": "출근 상태 확인",
|
||||
"description": "현재 출퇴근 상태 확인 (출근 전/출근 후)",
|
||||
"capture": {
|
||||
"variable": "attendanceStatus",
|
||||
"checkElements": [
|
||||
{ "selector": "button:has-text('출근하기')", "status": "not_checked_in" },
|
||||
{ "selector": "text=출근 완료", "status": "checked_in" },
|
||||
{ "selector": "button:has-text('퇴근하기')", "status": "ready_to_checkout" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-9",
|
||||
"name": "출근하기 (미출근 상태인 경우)",
|
||||
"description": "출근하기 버튼이 활성화된 경우 클릭하여 출근 기록",
|
||||
"condition": {
|
||||
"if": "{attendanceStatus} == 'not_checked_in'"
|
||||
},
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "출근하기" }
|
||||
],
|
||||
"waitFor": {
|
||||
"type": "text",
|
||||
"content": "출근 완료",
|
||||
"timeout": 5000
|
||||
},
|
||||
"expect": {
|
||||
"toast": ["출근", "완료", "성공"],
|
||||
"visible": ["출근 완료", "출근 시간"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-10",
|
||||
"name": "출근 완료 상태 확인",
|
||||
"description": "출근 완료 후 상태 및 출근 시간 표시 확인",
|
||||
"verify": {
|
||||
"visible": ["출근 완료"],
|
||||
"checkInTime": {
|
||||
"format": "HH:mm:ss",
|
||||
"displayed": true
|
||||
},
|
||||
"buttonState": {
|
||||
"출근하기": "hidden_or_disabled",
|
||||
"퇴근하기": "enabled_or_visible"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-11",
|
||||
"name": "퇴근하기 버튼 상태 확인",
|
||||
"description": "출근 완료 후 퇴근하기 버튼 활성화 여부 확인",
|
||||
"verify": {
|
||||
"button": {
|
||||
"target": "퇴근하기",
|
||||
"state": "visible",
|
||||
"note": "일부 시스템에서는 최소 근무 시간 후에만 활성화될 수 있음"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-12",
|
||||
"name": "퇴근하기 (선택적)",
|
||||
"description": "퇴근하기 버튼이 활성화된 경우 클릭하여 퇴근 기록",
|
||||
"optional": true,
|
||||
"condition": {
|
||||
"if": "button[name='퇴근하기']:enabled"
|
||||
},
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "퇴근하기" }
|
||||
],
|
||||
"waitFor": {
|
||||
"type": "text",
|
||||
"content": ["퇴근 완료", "퇴근 시간"],
|
||||
"timeout": 5000
|
||||
},
|
||||
"expect": {
|
||||
"toast": ["퇴근", "완료", "성공"],
|
||||
"visible": ["퇴근 완료", "퇴근 시간"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-13",
|
||||
"name": "최종 상태 확인",
|
||||
"description": "출퇴근 기록 후 최종 상태 확인",
|
||||
"verify": {
|
||||
"url": "/hr/attendance",
|
||||
"mapDisplayed": true,
|
||||
"attendanceRecorded": true
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
"assertions": [
|
||||
{
|
||||
"type": "url",
|
||||
"expected": "/hr/attendance",
|
||||
"message": "근태현황 페이지에 머물러야 함"
|
||||
},
|
||||
{
|
||||
"type": "permission",
|
||||
"name": "geolocation",
|
||||
"state": "granted",
|
||||
"message": "위치 정보 권한이 허용되어야 함"
|
||||
},
|
||||
{
|
||||
"type": "elementExists",
|
||||
"selector": "region[name='지도']",
|
||||
"message": "Google Map이 표시되어야 함"
|
||||
},
|
||||
{
|
||||
"type": "elementExists",
|
||||
"selector": "text=현재 시간",
|
||||
"message": "현재 시간이 표시되어야 함"
|
||||
}
|
||||
],
|
||||
|
||||
"cleanup": {
|
||||
"enabled": false,
|
||||
"description": "출퇴근 기록은 삭제하지 않음 (업무 데이터)",
|
||||
"note": "테스트 후 수동으로 관리자가 삭제 필요시 처리"
|
||||
},
|
||||
|
||||
"notes": {
|
||||
"testScope": "위치 권한 허용 -> 근태현황 페이지 이동 -> 출근/퇴근 기록 테스트",
|
||||
"antiPattern404": "직접 URL 접근 금지 - 반드시 메뉴 클릭으로 페이지 진입",
|
||||
"scrollRequired": "사이드바 스크롤을 통해 메뉴 항목 탐색 필수",
|
||||
"correctUrl": "/hr/attendance (기존 /ko/hr/attendance에서 수정됨)"
|
||||
},
|
||||
|
||||
"playwrightMcpInstructions": {
|
||||
"description": "Playwright MCP를 사용한 위치 권한 설정 방법",
|
||||
"beforeNavigation": [
|
||||
"1. 브라우저 navigate 전에 위치 권한 설정이 필요함",
|
||||
"2. Playwright MCP는 브라우저 컨텍스트 레벨에서 권한을 설정할 수 없으므로 UI 팝업 처리 필요"
|
||||
],
|
||||
"uiPermissionHandling": {
|
||||
"description": "위치 권한 팝업이 나타나면 '항상 허용' 버튼 클릭",
|
||||
"selectors": [
|
||||
"button:has-text('항상 허용')",
|
||||
"button:has-text('허용')",
|
||||
"button:has-text('Allow')"
|
||||
],
|
||||
"workflow": [
|
||||
"1. 페이지 로드 후 1-2초 대기",
|
||||
"2. 위치 권한 팝업 존재 여부 확인",
|
||||
"3. 팝업이 있으면 '항상 허용' 버튼 클릭",
|
||||
"4. 팝업이 없으면 이미 권한이 허용된 상태로 간주하고 진행"
|
||||
]
|
||||
},
|
||||
"mockGeolocation": {
|
||||
"description": "테스트용 가상 위치 설정",
|
||||
"latitude": 37.557358,
|
||||
"longitude": 126.864414,
|
||||
"note": "서울 영등포구 좌표 (테스트 회사 위치 가정)"
|
||||
}
|
||||
}
|
||||
}
|
||||
81
_backup_before_enhance/board-management.json
Normal file
81
_backup_before_enhance/board-management.json
Normal file
@@ -0,0 +1,81 @@
|
||||
{
|
||||
"id": "board-management",
|
||||
"name": "게시판 관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "게시판 > 게시판 관리 목록/검색/상세 기능 검증",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "게시판",
|
||||
"level2": "게시판 관리",
|
||||
"expectedUrl": "/board/board-management",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 게시판 > 게시판 관리",
|
||||
"action": "menu_navigate",
|
||||
"level1": "게시판",
|
||||
"level2": "게시판 관리",
|
||||
"expected": { "url_contains": "/board" }
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "목업 감지",
|
||||
"action": "verify_not_mockup"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "게시판 관리 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:게시판"]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "테이블 확인",
|
||||
"action": "verify_table"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "검색 기능",
|
||||
"action": "search",
|
||||
"value": "테스트"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "검색 후 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:게시판"]
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "첫 번째 행 클릭",
|
||||
"action": "click_first_row"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "상세 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:게시판"]
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "모달 닫기",
|
||||
"action": "close_modal_if_open"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "목록 복귀",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('목록'), a:has-text('목록')"
|
||||
}
|
||||
]
|
||||
}
|
||||
435
_backup_before_enhance/company-info.json
Normal file
435
_backup_before_enhance/company-info.json
Normal file
@@ -0,0 +1,435 @@
|
||||
{
|
||||
"id": "company-info",
|
||||
"name": "설정 - 회사정보",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "회사 정보 관리 기능 테스트 - 회사 정보 조회, 수정, 회사 추가 기능",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
|
||||
"navigation": {
|
||||
"targetUrl": "/company-info",
|
||||
"urlPattern": "/company-info|/ko/company-info|/settings/company-info",
|
||||
"menuHints": ["회사정보", "회사 정보", "설정"]
|
||||
},
|
||||
"menuNavigation": {
|
||||
"level1": "설정",
|
||||
"level2": "회사정보",
|
||||
"expectedUrl": "/company-info",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"menuNavigationEnhanced": {
|
||||
"strategy": "scroll-and-search",
|
||||
"description": "사이드바를 스크롤하며 메뉴를 찾고 클릭하여 404를 방지",
|
||||
"level1": "설정",
|
||||
"level2": "회사정보",
|
||||
"alternativeLevel1Names": ["설정", "Settings", "환경설정", "시스템설정", "관리"],
|
||||
"alternativeLevel2Names": ["회사정보", "회사 정보", "Company Info", "회사관리", "기업정보"],
|
||||
"fallbackUrls": [
|
||||
"/company-info",
|
||||
"/ko/company-info",
|
||||
"/settings/company-info",
|
||||
"/ko/settings/company-info"
|
||||
],
|
||||
"scrollConfig": {
|
||||
"sidebarSelector": "nav, aside, [role='navigation'], .sidebar, #sidebar",
|
||||
"menuItemSelector": "a, button, [role='menuitem'], [role='treeitem']",
|
||||
"scrollStep": 200,
|
||||
"maxScrollAttempts": 10,
|
||||
"scrollDelay": 300
|
||||
}
|
||||
},
|
||||
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/v1/company-info",
|
||||
"description": "회사 정보 조회"
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"path": "/api/v1/company-info/:id",
|
||||
"description": "회사 정보 수정"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/v1/company-info",
|
||||
"description": "회사 추가"
|
||||
}
|
||||
],
|
||||
|
||||
"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 }
|
||||
],
|
||||
"verification": [
|
||||
"사이드바가 화면에 보이는지 확인",
|
||||
"모든 메뉴가 펼쳐졌는지 확인"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"name": "1차 메뉴 찾기: 설정 (스크롤 포함)",
|
||||
"description": "사이드바를 스크롤하며 '설정' 메뉴를 찾아 클릭",
|
||||
"actions": [
|
||||
{
|
||||
"type": "scrollAndFind",
|
||||
"target": "설정",
|
||||
"alternativeTexts": ["설정", "Settings", "환경설정", "시스템설정"],
|
||||
"scrollContainer": "sidebar",
|
||||
"maxAttempts": 10,
|
||||
"description": "스크롤하며 설정 메뉴 찾기"
|
||||
},
|
||||
{ "type": "wait", "duration": 300 },
|
||||
{ "type": "click_if_exists", "target": "설정", "description": "설정 메뉴 클릭" },
|
||||
{ "type": "wait", "duration": 500, "description": "서브메뉴 펼쳐지기 대기" },
|
||||
{ "type": "screenshot", "name": "settings_menu_expanded" }
|
||||
],
|
||||
"verification": [
|
||||
"설정 메뉴가 클릭되었는지 확인",
|
||||
"서브메뉴가 펼쳐졌는지 확인",
|
||||
"하위 메뉴 항목들이 보이는지 확인"
|
||||
],
|
||||
"fallback": {
|
||||
"if": "메뉴를 찾을 수 없음",
|
||||
"then": "사이드바 전체를 스크롤하며 재탐색"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "2차 메뉴 찾기: 회사정보 (스크롤 포함)",
|
||||
"description": "서브메뉴에서 '회사정보'를 찾아 클릭",
|
||||
"actions": [
|
||||
{
|
||||
"type": "scrollAndFind",
|
||||
"target": "회사정보",
|
||||
"alternativeTexts": ["회사정보", "회사 정보", "Company Info", "회사관리"],
|
||||
"scrollContainer": "submenu",
|
||||
"maxAttempts": 5,
|
||||
"description": "서브메뉴에서 회사정보 찾기"
|
||||
},
|
||||
{ "type": "wait", "duration": 200 },
|
||||
{ "type": "click_if_exists", "target": "회사정보", "description": "회사정보 메뉴 클릭" },
|
||||
{ "type": "wait", "target": "페이지 로드 완료", "timeout": 10000 },
|
||||
{ "type": "screenshot", "name": "company_info_page" }
|
||||
],
|
||||
"verification": [
|
||||
"회사정보 메뉴 클릭 성공",
|
||||
"페이지 이동 또는 컨텐츠 로드"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "404 에러 감지 및 대체 경로 시도",
|
||||
"description": "페이지 로드 후 404 에러 여부 확인, 404시 대체 경로 탐색",
|
||||
"actions": [
|
||||
{ "type": "wait", "duration": 1000 },
|
||||
{ "type": "checkFor404", "indicators": [
|
||||
"페이지를 찾을 수 없습니다",
|
||||
"404",
|
||||
"Not Found",
|
||||
"존재하지 않거나"
|
||||
]},
|
||||
{ "type": "screenshot", "name": "page_load_result" }
|
||||
],
|
||||
"verification": [
|
||||
"현재 페이지가 404인지 확인"
|
||||
],
|
||||
"onError404": {
|
||||
"description": "404 에러 발생 시 대체 URL 시도",
|
||||
"actions": [
|
||||
{ "type": "log", "message": "404 감지 - 대체 경로 탐색 시작" },
|
||||
{
|
||||
"type": "tryAlternativeUrls",
|
||||
"urls": [
|
||||
"/company-info",
|
||||
"/ko/company-info"
|
||||
],
|
||||
"stopOnSuccess": true
|
||||
},
|
||||
{
|
||||
"type": "ifStillFailed",
|
||||
"action": "navigateViaMenuClick",
|
||||
"description": "URL 직접 접근 실패 시 메뉴 클릭으로 재시도"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "페이지 정상 로드 확인",
|
||||
"description": "회사정보 페이지가 정상적으로 로드되었는지 확인",
|
||||
"actions": [
|
||||
{ "type": "verify", "target": "pageTitle", "contains": ["회사정보", "회사 정보", "Company"] },
|
||||
{ "type": "verify", "target": "pageContent", "notContains": ["404", "찾을 수 없습니다", "Not Found"] }
|
||||
],
|
||||
"verification": [
|
||||
"페이지 제목 '회사정보' 또는 관련 텍스트 표시",
|
||||
"404 에러 메시지 미표시",
|
||||
"콘텐츠가 정상 렌더링됨"
|
||||
],
|
||||
"successCriteria": {
|
||||
"urlPattern": "/company-info",
|
||||
"requiredElements": ["회사", "회사명", "대표자명"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"step": 5,
|
||||
"name": "페이지 제목 확인",
|
||||
"action": "verify",
|
||||
"target": "heading",
|
||||
"expected": "회사정보",
|
||||
"validation": "페이지 제목이 '회사정보'로 표시됨"
|
||||
},
|
||||
{
|
||||
"step": 6,
|
||||
"name": "회사 추가 버튼 존재 확인",
|
||||
"action": "verify",
|
||||
"target": "button[text='회사 추가']",
|
||||
"expected": "button exists",
|
||||
"validation": "회사 추가 버튼이 표시됨"
|
||||
},
|
||||
{
|
||||
"step": 7,
|
||||
"name": "수정 버튼 존재 확인",
|
||||
"action": "verify",
|
||||
"target": "button[text='수정']",
|
||||
"expected": "button exists",
|
||||
"validation": "수정 버튼이 표시됨"
|
||||
},
|
||||
{
|
||||
"step": 8,
|
||||
"name": "회사명 필드 확인",
|
||||
"action": "verify",
|
||||
"target": "textbox[label='회사명'][disabled]",
|
||||
"expected": "프론트_테스트회사",
|
||||
"validation": "회사명이 표시되고 비활성화 상태"
|
||||
},
|
||||
{
|
||||
"step": 9,
|
||||
"name": "대표자명 필드 확인",
|
||||
"action": "verify",
|
||||
"target": "textbox[label='대표자명'][disabled]",
|
||||
"expected": "프론트",
|
||||
"validation": "대표자명이 표시되고 비활성화 상태"
|
||||
},
|
||||
{
|
||||
"step": 10,
|
||||
"name": "업태 필드 확인",
|
||||
"action": "verify",
|
||||
"target": "textbox[label='업태'][disabled]",
|
||||
"expected": "업태명",
|
||||
"validation": "업태가 표시되고 비활성화 상태"
|
||||
},
|
||||
{
|
||||
"step": 11,
|
||||
"name": "업종 필드 확인",
|
||||
"action": "verify",
|
||||
"target": "textbox[label='업종'][disabled]",
|
||||
"expected": "업종명",
|
||||
"validation": "업종이 표시되고 비활성화 상태"
|
||||
},
|
||||
{
|
||||
"step": 12,
|
||||
"name": "주소 필드 확인",
|
||||
"action": "verify",
|
||||
"target": "textbox[label='주소명'][disabled]",
|
||||
"expected": "주소 표시",
|
||||
"validation": "주소가 표시되고 비활성화 상태"
|
||||
},
|
||||
{
|
||||
"step": 13,
|
||||
"name": "이메일 필드 확인",
|
||||
"action": "verify",
|
||||
"target": "textbox[label='이메일 (아이디)'][disabled]",
|
||||
"expected": "이메일 표시",
|
||||
"validation": "이메일이 표시되고 비활성화 상태"
|
||||
},
|
||||
{
|
||||
"step": 14,
|
||||
"name": "사업자등록번호 필드 확인",
|
||||
"action": "verify",
|
||||
"target": "textbox[label='사업자등록번호'][disabled]",
|
||||
"expected": "사업자등록번호 표시",
|
||||
"validation": "사업자등록번호가 표시되고 비활성화 상태"
|
||||
},
|
||||
{
|
||||
"step": 15,
|
||||
"name": "수정 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "button[text='수정']",
|
||||
"expected": "edit mode enabled",
|
||||
"validation": "수정 모드로 전환됨"
|
||||
},
|
||||
{
|
||||
"step": 16,
|
||||
"name": "수정 모드 - 필드 활성화 확인",
|
||||
"action": "verify",
|
||||
"target": "textbox:not([disabled])",
|
||||
"expected": "fields enabled",
|
||||
"validation": "텍스트 필드들이 활성화됨"
|
||||
},
|
||||
{
|
||||
"step": 17,
|
||||
"name": "취소 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "button[text='취소']",
|
||||
"expected": "edit mode disabled",
|
||||
"validation": "조회 모드로 복귀"
|
||||
},
|
||||
{
|
||||
"step": 18,
|
||||
"name": "회사 추가 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "button[text='회사 추가']",
|
||||
"expected": "dialog opened",
|
||||
"validation": "회사 추가 다이얼로그가 열림"
|
||||
},
|
||||
{
|
||||
"step": 19,
|
||||
"name": "회사 추가 다이얼로그 확인",
|
||||
"action": "verify",
|
||||
"target": "dialog",
|
||||
"expected": "회사 추가 다이얼로그 표시",
|
||||
"validation": "다이얼로그 제목, 입력 필드, 버튼 확인"
|
||||
},
|
||||
{
|
||||
"step": 20,
|
||||
"name": "다이얼로그 닫기",
|
||||
"action": "click_if_exists",
|
||||
"target": "dialog button[text='취소']",
|
||||
"expected": "dialog closed",
|
||||
"validation": "다이얼로그가 닫힘"
|
||||
},
|
||||
{
|
||||
"step": 21,
|
||||
"name": "수정 모드에서 데이터 변경 테스트",
|
||||
"description": "실제 데이터를 수정하고 저장 기능 검증",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "수정", "description": "수정 모드 진입" }
|
||||
],
|
||||
"expect": {
|
||||
"fieldsEnabled": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"step": 22,
|
||||
"name": "업태 필드 수정",
|
||||
"description": "업태 필드 값 변경",
|
||||
"actions": [
|
||||
{ "type": "clear", "target": "업태" },
|
||||
{ "type": "fill", "target": "업태", "value": "테스트업태_수정" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"step": 23,
|
||||
"name": "저장 버튼 클릭",
|
||||
"description": "수정된 회사 정보 저장",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "저장" }
|
||||
],
|
||||
"waitFor": {
|
||||
"type": "apiResponse",
|
||||
"method": "PUT",
|
||||
"timeout": 5000
|
||||
},
|
||||
"expect": {
|
||||
"toast": ["수정", "완료", "성공", "저장"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"step": 24,
|
||||
"name": "⚠️ 필수 검증: 수정 데이터 반영 확인",
|
||||
"note": "토스트 성공 메시지만으로 PASS 판정 불가. 실제 데이터 변경 확인 필수!",
|
||||
"description": "수정된 업태 값이 반영되었는지 확인",
|
||||
"verify": {
|
||||
"fieldValue": {
|
||||
"target": "업태",
|
||||
"expected": "테스트업태_수정"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"step": 25,
|
||||
"name": "회사 추가 다이얼로그 열기",
|
||||
"description": "회사 추가 버튼 클릭하여 다이얼로그 열기",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "회사 추가" }
|
||||
],
|
||||
"expect": {
|
||||
"dialog": true,
|
||||
"visible": ["회사명", "대표자명", "사업자등록번호", "등록", "취소"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"step": 26,
|
||||
"name": "새 회사 정보 입력",
|
||||
"description": "회사 추가 다이얼로그에서 필수 정보 입력",
|
||||
"actions": [
|
||||
{ "type": "fill", "target": "회사명", "value": "테스트회사_{timestamp}" },
|
||||
{ "type": "fill", "target": "대표자명", "value": "테스트대표" },
|
||||
{ "type": "fill", "target": "사업자등록번호", "value": "123-45-67890" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"step": 27,
|
||||
"name": "회사 등록",
|
||||
"description": "등록 버튼 클릭하여 새 회사 등록",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "등록" }
|
||||
],
|
||||
"waitFor": {
|
||||
"type": "apiResponse",
|
||||
"method": "POST",
|
||||
"timeout": 5000
|
||||
},
|
||||
"expect": {
|
||||
"toast": ["등록", "완료", "성공"],
|
||||
"dialogClosed": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"step": 28,
|
||||
"name": "⚠️ 필수 검증: 회사 등록 반영 확인",
|
||||
"note": "토스트 성공 메시지만으로 PASS 판정 불가. 실제 데이터 등록 확인 필수!",
|
||||
"description": "등록된 회사가 목록에 표시되는지 확인",
|
||||
"verify": {
|
||||
"visible": "테스트회사"
|
||||
}
|
||||
},
|
||||
{
|
||||
"step": 29,
|
||||
"name": "원복: 업태 필드 원래 값으로 복구",
|
||||
"description": "테스트 후 원래 값으로 복구",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "수정" },
|
||||
{ "type": "clear", "target": "업태" },
|
||||
{ "type": "fill", "target": "업태", "value": "업태명" },
|
||||
{ "type": "click_if_exists", "target": "저장" }
|
||||
],
|
||||
"expect": {
|
||||
"toast": ["수정", "완료", "성공", "저장"]
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
"notes": [
|
||||
"직접 URL 접근 금지: 반드시 메뉴 클릭으로 페이지 진입 (404 방지)",
|
||||
"스크롤 필수: 사이드바가 길 경우 메뉴가 화면 밖에 있을 수 있음",
|
||||
"대체 경로: 메뉴명이 변경되었을 수 있으므로 다양한 이름으로 탐색",
|
||||
"메뉴 계층: 설정 > 회사정보"
|
||||
]
|
||||
}
|
||||
164
_backup_before_enhance/customer-event.json
Normal file
164
_backup_before_enhance/customer-event.json
Normal file
@@ -0,0 +1,164 @@
|
||||
{
|
||||
"id": "customer-event",
|
||||
"name": "이벤트 게시판 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "고객센터 > 이벤트 게시판 메뉴의 이벤트 목록 조회/상세보기 기능 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "고객센터",
|
||||
"level2": "이벤트 게시판",
|
||||
"expectedUrl": "/customer-center/events",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 고객센터 > 이벤트 게시판",
|
||||
"action": "menu_navigate",
|
||||
"level1": "고객센터",
|
||||
"level2": "이벤트 게시판",
|
||||
"expected": {
|
||||
"url_contains": "/customer-center",
|
||||
"visible": ["이벤트"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"이벤트 목록 표시",
|
||||
"이벤트 카드 또는 리스트"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "이벤트 페이지 구조 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"이벤트 목록 (카드 또는 테이블)",
|
||||
"이벤트 상태 표시 (진행중/종료)",
|
||||
"검색 기능"
|
||||
],
|
||||
"expected": "이벤트 페이지 구조 정상"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 이벤트 목록 데이터 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"이벤트 항목 존재 또는 '등록된 이벤트 없음' 메시지"
|
||||
],
|
||||
"expected": "이벤트 데이터 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 상태별 필터",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"전체/진행중/종료 필터 가능"
|
||||
],
|
||||
"expected": "상태 필터 표시"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 이벤트 상세 보기",
|
||||
"action": "click_if_exists",
|
||||
"target": "[class*='event']:first-child, table tbody tr:first-child, [class*='card']:first-child",
|
||||
"expected": {
|
||||
"detail_view": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "이벤트 상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"이벤트 제목",
|
||||
"이벤트 기간",
|
||||
"이벤트 내용",
|
||||
"이벤트 이미지 (있을 경우)"
|
||||
],
|
||||
"expected": "이벤트 상세 정보 표시"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "이벤트 참여 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"참여하기 버튼 존재 여부 (진행중 이벤트)"
|
||||
],
|
||||
"expected": "참여 버튼 확인"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "공유 기능 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"공유 버튼 또는 링크 복사 기능"
|
||||
],
|
||||
"expected": "공유 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "목록으로 돌아가기",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('목록'), a:has-text('목록'), [class*='back']",
|
||||
"expected": "목록 페이지로 복귀"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "페이지네이션 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"페이지 번호 또는 더보기 버튼"
|
||||
],
|
||||
"expected": "페이지네이션 표시"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "이벤트 기간 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"시작일/종료일 표시",
|
||||
"D-Day 또는 남은 기간 표시"
|
||||
],
|
||||
"expected": "기간 정보 표시"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/customer/events",
|
||||
"description": "이벤트 목록 조회"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/customer/events/:id",
|
||||
"description": "이벤트 상세 조회"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"criteria": "이벤트 목록, 이벤트 카드/리스트 존재"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"note": "조회 전용 페이지로 데이터 변경 없음"
|
||||
}
|
||||
}
|
||||
185
_backup_before_enhance/customer-faq.json
Normal file
185
_backup_before_enhance/customer-faq.json
Normal file
@@ -0,0 +1,185 @@
|
||||
{
|
||||
"id": "customer-faq",
|
||||
"name": "FAQ 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": [
|
||||
"error",
|
||||
"fail",
|
||||
"timeout",
|
||||
"404",
|
||||
"500",
|
||||
"blocked"
|
||||
]
|
||||
},
|
||||
"description": "고객센터 > FAQ 메뉴의 자주 묻는 질문 조회/검색/카테고리 필터 기능 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "고객센터",
|
||||
"level2": "FAQ",
|
||||
"expectedUrl": "/customer-center/faq",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 고객센터 > FAQ",
|
||||
"action": "menu_navigate",
|
||||
"level1": "고객센터",
|
||||
"level2": "FAQ",
|
||||
"expected": {
|
||||
"url_contains": "/customer-center/faq",
|
||||
"visible": [
|
||||
"FAQ",
|
||||
"자주 묻는 질문"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"FAQ 목록 표시",
|
||||
"카테고리 또는 검색 기능 존재"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "FAQ 페이지 구조 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"FAQ 항목 목록 (아코디언 또는 리스트)",
|
||||
"카테고리 탭/필터",
|
||||
"검색 기능"
|
||||
],
|
||||
"expected": "FAQ 페이지 구조 정상"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"phase": "READ",
|
||||
"name": "[READ] FAQ 목록 데이터 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"FAQ 항목 존재 또는 '등록된 FAQ 없음' 메시지"
|
||||
],
|
||||
"expected": "FAQ 데이터 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "READ",
|
||||
"name": "[READ] FAQ 항목 펼치기",
|
||||
"action": "click_if_exists",
|
||||
"target": "[class*='accordion']:first-child, [class*='faq']:first-child, table tbody tr:first-child",
|
||||
"expected": {
|
||||
"accordion_open": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "FAQ 답변 내용 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"답변 내용 표시"
|
||||
],
|
||||
"expected": "FAQ 답변 표시"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 카테고리 필터",
|
||||
"action": "verify_element",
|
||||
"target": "[class*='category'], [class*='tab']",
|
||||
"expected": "카테고리 선택 가능"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 카테고리 선택 후 결과",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"해당 카테고리 FAQ만 표시"
|
||||
],
|
||||
"expected": "카테고리 필터 동작"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"phase": "SEARCH",
|
||||
"name": "[SEARCH] FAQ 검색",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[type='search'], input[placeholder*='검색']",
|
||||
"value": "테스트",
|
||||
"submit": true
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"phase": "SEARCH",
|
||||
"name": "[SEARCH] 검색 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"검색 결과 표시 또는 결과 없음 메시지"
|
||||
],
|
||||
"expected": "검색 기능 동작"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "FAQ 접기/펼치기 토글",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"접기/펼치기 아이콘 또는 버튼"
|
||||
],
|
||||
"expected": "토글 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "전체 보기/접기",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"전체 펼치기/접기 버튼 존재 여부"
|
||||
],
|
||||
"expected": "전체 토글 기능 확인"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/customer/faq",
|
||||
"description": "FAQ 목록 조회"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/customer/faq/categories",
|
||||
"description": "FAQ 카테고리 조회"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 3,
|
||||
"name": "검색/필터",
|
||||
"steps": [
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10
|
||||
],
|
||||
"criteria": "카테고리 필터 + 검색 기능 동작"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [
|
||||
2
|
||||
],
|
||||
"criteria": "FAQ 목록, 카테고리/검색 기능 존재"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"note": "조회 전용 페이지로 데이터 변경 없음"
|
||||
}
|
||||
}
|
||||
201
_backup_before_enhance/customer-notice.json
Normal file
201
_backup_before_enhance/customer-notice.json
Normal file
@@ -0,0 +1,201 @@
|
||||
{
|
||||
"id": "customer-notice",
|
||||
"name": "공지사항 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "고객센터 > 공지사항 메뉴의 공지사항 조회/검색/상세보기 기능 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "고객센터",
|
||||
"level2": "공지사항",
|
||||
"expectedUrl": "/customer-center/notices",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 고객센터 > 공지사항",
|
||||
"action": "menu_navigate",
|
||||
"level1": "고객센터",
|
||||
"level2": "공지사항",
|
||||
"expected": {
|
||||
"url_contains": "/customer-center/notices",
|
||||
"visible": ["공지사항"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"공지사항 목록 표시",
|
||||
"검색 기능 존재",
|
||||
"목록 테이블 또는 카드"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "공지사항 목록 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
"번호 컬럼",
|
||||
"제목 컬럼",
|
||||
"작성자 컬럼",
|
||||
"작성일 컬럼",
|
||||
"조회수 컬럼"
|
||||
],
|
||||
"expected": "공지사항 목록 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 공지사항 목록 데이터 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"공지사항 데이터 행 존재 또는 '등록된 공지 없음' 메시지"
|
||||
],
|
||||
"expected": "공지사항 데이터 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "SEARCH",
|
||||
"name": "[SEARCH] 공지사항 검색",
|
||||
"action": "fill",
|
||||
"target": "input[type='search'], input[placeholder*='검색']",
|
||||
"value": "테스트",
|
||||
"submit": true
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"phase": "SEARCH",
|
||||
"name": "[SEARCH] 검색 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"검색 결과 표시 또는 결과 없음 메시지"
|
||||
],
|
||||
"expected": "검색 기능 동작"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "SEARCH",
|
||||
"name": "[SEARCH] 검색 초기화",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('초기화'), button:has-text('전체'), button[class*='clear']",
|
||||
"expected": "검색 초기화"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 공지사항 상세 보기",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:first-child, [class*='list'] [class*='item']:first-child",
|
||||
"expected": {
|
||||
"detail_view": true,
|
||||
"url_change": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "상세 페이지 구조 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"제목 표시",
|
||||
"작성자 표시",
|
||||
"작성일 표시",
|
||||
"내용 표시"
|
||||
],
|
||||
"expected": "상세 페이지 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "첨부파일 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"첨부파일 영역 존재 여부"
|
||||
],
|
||||
"expected": "첨부파일 영역 확인"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "이전/다음 글 네비게이션",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"이전 글 링크 또는 버튼",
|
||||
"다음 글 링크 또는 버튼"
|
||||
],
|
||||
"expected": "글 네비게이션 표시"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "목록으로 돌아가기",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('목록'), a:has-text('목록'), [class*='back']",
|
||||
"expected": "목록 페이지로 복귀"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"name": "페이지네이션 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"페이지 번호 표시",
|
||||
"이전/다음 페이지 버튼"
|
||||
],
|
||||
"expected": "페이지네이션 표시"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"name": "정렬 기능 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"최신순/조회순 정렬 가능"
|
||||
],
|
||||
"expected": "정렬 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"name": "중요 공지 표시 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"중요/고정 공지 상단 표시 여부"
|
||||
],
|
||||
"expected": "중요 공지 표시 확인"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/customer-center/noticess",
|
||||
"description": "공지사항 목록 조회"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/customer-center/noticess/:id",
|
||||
"description": "공지사항 상세 조회"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 3,
|
||||
"name": "검색/필터",
|
||||
"steps": [5, 6, 7],
|
||||
"criteria": "검색 기능 동작"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"criteria": "공지사항 목록, 검색 기능, 목록 표시 존재"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"note": "조회 전용 페이지로 데이터 변경 없음"
|
||||
}
|
||||
}
|
||||
150
_backup_before_enhance/department-add.json
Normal file
150
_backup_before_enhance/department-add.json
Normal file
@@ -0,0 +1,150 @@
|
||||
{
|
||||
"enabled": true,
|
||||
"id": "department-add",
|
||||
"name": "부서관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "인사관리 > 부서관리 메뉴의 부서 트리/목록 조회 및 UI 검증 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "인사관리",
|
||||
"level2": "부서관리",
|
||||
"expectedUrl": "/hr/department-management",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 인사관리 > 부서관리",
|
||||
"action": "menu_navigate",
|
||||
"level1": "인사관리",
|
||||
"level2": "부서관리",
|
||||
"expected": {
|
||||
"url_contains": "/hr/department",
|
||||
"visible": ["부서관리"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"부서 목록 또는 트리 표시",
|
||||
"부서 추가 버튼 존재"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "부서 트리/목록 구조 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"부서 목록 또는 트리 구조 표시",
|
||||
"추가 버튼 존재",
|
||||
"부서 정보 표시"
|
||||
],
|
||||
"expected": "부서관리 페이지 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 부서 목록 데이터 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"부서 목록 데이터 표시됨"
|
||||
],
|
||||
"expected": "부서 목록 정상"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 첫 번째 부서 노드 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:first-child, [class*='tree'] > *:first-child, li:first-child"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 부서 상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"부서 상세 정보 표시"
|
||||
],
|
||||
"expected": "부서 상세 정보 확인"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "부서 추가 버튼 확인",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('추가'), button:has-text('등록'), button:has-text('부서 추가')"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "추가 폼/모달 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"부서명 입력 필드 존재",
|
||||
"저장/등록 버튼 존재"
|
||||
],
|
||||
"expected": "부서 추가 폼 표시"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "추가 모달 닫기",
|
||||
"action": "close_modal_if_open",
|
||||
"expected": "모달 닫힘"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "부서 트리 구조 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"부서 계층 구조 표시"
|
||||
],
|
||||
"expected": "트리 구조 확인"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "삭제 버튼 존재 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"삭제 버튼 존재 여부"
|
||||
],
|
||||
"expected": "삭제 기능 확인"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "부서관리 페이지 최종 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"부서관리 페이지 정상 동작"
|
||||
],
|
||||
"expected": "페이지 정상 확인"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/departments",
|
||||
"description": "부서 목록 조회"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"criteria": "부서 목록, 추가 버튼 존재"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"note": "READ-only 패턴으로 안정성 우선, CRUD 테스트 제거"
|
||||
}
|
||||
}
|
||||
468
_backup_before_enhance/deposit-management.json
Normal file
468
_backup_before_enhance/deposit-management.json
Normal file
@@ -0,0 +1,468 @@
|
||||
{
|
||||
"id": "deposit-management",
|
||||
"name": "입금관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "입금관리 목록 조회, 계정과목명 일괄변경, 상세 수정 기능 E2E 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"url": "/ko/accounting/deposits",
|
||||
"navigation": {
|
||||
"targetUrl": "/accounting/deposits",
|
||||
"urlPattern": "/accounting/deposits|/ko/accounting/deposits",
|
||||
"menuHints": ["입금관리", "입금 관리", "회계관리"]
|
||||
},
|
||||
"menuNavigation": {
|
||||
"level1": "회계관리",
|
||||
"level2": "입금관리",
|
||||
"expectedUrl": "/ko/accounting/deposits",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"menuNavigationEnhanced": {
|
||||
"strategy": "scroll-and-search",
|
||||
"description": "사이드바를 스크롤하며 메뉴를 찾고 클릭하여 404를 방지",
|
||||
"level1": "회계관리",
|
||||
"level2": "입금관리",
|
||||
"alternativeLevel1Names": ["회계관리", "회계 관리", "Accounting"],
|
||||
"alternativeLevel2Names": ["입금관리", "입금 관리", "Deposits"],
|
||||
"scrollConfig": {
|
||||
"sidebarSelector": "nav, aside, [role='navigation'], .sidebar, #sidebar",
|
||||
"menuItemSelector": "a, button, [role='menuitem'], [role='treeitem']",
|
||||
"scrollStep": 200,
|
||||
"maxScrollAttempts": 10,
|
||||
"scrollDelay": 300
|
||||
}
|
||||
},
|
||||
"timeout": 60000,
|
||||
"tags": ["accounting", "deposit", "crud"],
|
||||
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
|
||||
"steps": [
|
||||
{
|
||||
"id": "step-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 }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "step-1",
|
||||
"name": "2단계 메뉴 진입: 회계관리 > 입금관리",
|
||||
"description": "사이드바를 스크롤하며 회계관리 > 입금관리 메뉴를 찾아 클릭",
|
||||
"actions": [
|
||||
{
|
||||
"type": "scrollAndFind",
|
||||
"target": "회계관리",
|
||||
"alternativeTexts": ["회계관리", "회계 관리", "Accounting"],
|
||||
"scrollContainer": "sidebar",
|
||||
"maxAttempts": 10,
|
||||
"description": "스크롤하며 회계관리 메뉴 찾기"
|
||||
},
|
||||
{ "type": "click_if_exists", "target": "회계관리", "description": "회계관리 메뉴 클릭" },
|
||||
{ "type": "wait", "duration": 500, "description": "서브메뉴 펼쳐지기 대기" },
|
||||
{
|
||||
"type": "scrollAndFind",
|
||||
"target": "입금관리",
|
||||
"alternativeTexts": ["입금관리", "입금 관리", "Deposits"],
|
||||
"scrollContainer": "submenu",
|
||||
"maxAttempts": 5,
|
||||
"description": "서브메뉴에서 입금관리 찾기"
|
||||
},
|
||||
{ "type": "click_if_exists", "target": "입금관리", "description": "입금관리 메뉴 클릭" },
|
||||
{ "type": "wait", "target": "페이지 로드 완료", "timeout": 10000 }
|
||||
],
|
||||
"expect": {
|
||||
"url": "/accounting/deposits",
|
||||
"visible": ["입금관리", "총 입금"]
|
||||
},
|
||||
"verification": [
|
||||
"회계관리 메뉴가 펼쳐졌는지 확인",
|
||||
"입금관리 서브메뉴 클릭 성공",
|
||||
"404 에러 없이 페이지 로드 완료"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "step-2",
|
||||
"name": "목록 페이지 구조 확인",
|
||||
"description": "테이블 및 필터 요소 확인",
|
||||
"expect": {
|
||||
"visible": ["입금일", "입금계좌", "입금자명", "입금금액", "거래처", "적요", "입금유형"],
|
||||
"elements": {
|
||||
"statisticsCards": ["총 입금", "당월 입금", "거래처 미설정", "입금유형 미설정"],
|
||||
"filters": ["계정과목명", "저장", "새로고침"],
|
||||
"pagination": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-3",
|
||||
"name": "계정과목명 드롭다운 옵션 확인",
|
||||
"description": "계정과목명 일괄변경 드롭다운 옵션 검증",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "계정과목명 드롭다운", "description": "드롭다운 열기" }
|
||||
],
|
||||
"expect": {
|
||||
"options": ["미설정", "매출대금", "선수금", "가수금", "임대수익", "이자수익", "보증금 반환", "차입금", "자본금", "부가세 환급", "기타"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-4",
|
||||
"name": "체크박스 선택 후 계정과목명 일괄변경",
|
||||
"description": "테이블 행 선택 후 계정과목명 일괄변경 저장",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "첫 번째 행 체크박스", "description": "행 선택" },
|
||||
{ "type": "click_if_exists", "target": "계정과목명 드롭다운", "description": "드롭다운 열기" },
|
||||
{ "type": "click_if_exists", "target": "매출대금", "description": "매출대금 선택" },
|
||||
{ "type": "click_if_exists", "target": "저장", "description": "저장 버튼 클릭" }
|
||||
],
|
||||
"expect": {
|
||||
"dialog": "확인 다이얼로그 표시",
|
||||
"toast": "변경 완료 메시지"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-4-1",
|
||||
"name": "⚠️ 필수 검증: 계정과목명 변경 데이터 반영 확인",
|
||||
"note": "토스트 성공 메시지만으로 PASS 판정 불가. 실제 데이터 변경 확인 필수!",
|
||||
"description": "저장 후 테이블에서 변경된 입금유형 값 확인",
|
||||
"expect": {
|
||||
"tableCell": {
|
||||
"row": 1,
|
||||
"column": "입금유형",
|
||||
"value": "매출대금"
|
||||
}
|
||||
},
|
||||
"knownBugReference": "BUG-SALES-20260115-001 (매출관리 동일 버그 확인 필요)"
|
||||
},
|
||||
{
|
||||
"id": "step-5",
|
||||
"name": "입금 상세 페이지 이동",
|
||||
"description": "테이블 행 클릭하여 상세 페이지로 이동",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "테이블 첫 번째 행", "description": "행 클릭 (체크박스 제외 영역)" }
|
||||
],
|
||||
"expect": {
|
||||
"url": "/accounting/deposits/{id}",
|
||||
"visible": ["입금 상세", "기본 정보", "목록", "삭제", "수정"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-6",
|
||||
"name": "상세 페이지 읽기 모드 필드 확인",
|
||||
"description": "수정 전 필드들이 비활성화 상태인지 확인",
|
||||
"expect": {
|
||||
"fields": [
|
||||
{ "name": "입금일", "disabled": true },
|
||||
{ "name": "입금계좌", "disabled": true },
|
||||
{ "name": "입금자명", "disabled": true },
|
||||
{ "name": "입금금액", "disabled": true },
|
||||
{ "name": "적요", "disabled": true },
|
||||
{ "name": "거래처", "disabled": true },
|
||||
{ "name": "입금 유형", "disabled": true }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-7",
|
||||
"name": "수정 모드 전환",
|
||||
"description": "수정 버튼 클릭하여 편집 모드로 전환",
|
||||
"click": "수정",
|
||||
"expect": {
|
||||
"url": "/accounting/deposits/{id}?mode=edit",
|
||||
"visible": ["입금 수정", "취소", "저장"],
|
||||
"notVisible": ["목록", "삭제", "수정"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-8",
|
||||
"name": "수정 모드 필드 활성화 검증",
|
||||
"description": "수정 가능한 필드와 불가능한 필드 확인",
|
||||
"expect": {
|
||||
"fields": [
|
||||
{ "name": "입금일", "disabled": true, "note": "은행데이터 - 수정 불가" },
|
||||
{ "name": "입금계좌", "disabled": true, "note": "은행데이터 - 수정 불가" },
|
||||
{ "name": "입금자명", "disabled": true, "note": "은행데이터 - 수정 불가" },
|
||||
{ "name": "입금금액", "disabled": true, "note": "은행데이터 - 수정 불가" },
|
||||
{ "name": "적요", "disabled": false, "editable": true },
|
||||
{ "name": "거래처", "disabled": false, "type": "combobox", "editable": true },
|
||||
{ "name": "입금 유형", "disabled": false, "type": "combobox", "editable": true }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-9",
|
||||
"name": "거래처 드롭다운 옵션 확인",
|
||||
"description": "거래처 선택 드롭다운 옵션 검증",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "거래처 드롭다운", "description": "드롭다운 열기" }
|
||||
],
|
||||
"expect": {
|
||||
"options": ["거래처테스트", "아크더레드", "코브라브릿지", "가우스전자", "아크아크"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-10",
|
||||
"name": "입금 유형 드롭다운 옵션 확인",
|
||||
"description": "입금 유형 선택 드롭다운 옵션 검증",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "입금 유형 드롭다운", "description": "드롭다운 열기" }
|
||||
],
|
||||
"expect": {
|
||||
"options": ["미설정", "매출대금", "선수금", "가수금", "임대수익", "이자수익", "보증금 반환", "차입금", "자본금", "부가세 환급", "기타"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-11",
|
||||
"name": "수정 데이터 입력",
|
||||
"description": "수정 가능한 필드에 테스트 데이터 입력",
|
||||
"form": {
|
||||
"fields": [
|
||||
{ "name": "적요", "type": "text", "value": "테스트 적요 수정" }
|
||||
]
|
||||
},
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "거래처 드롭다운", "description": "거래처 드롭다운 열기" },
|
||||
{ "type": "click_if_exists", "target": "거래처테스트", "description": "거래처 선택" },
|
||||
{ "type": "click_if_exists", "target": "입금 유형 드롭다운", "description": "입금 유형 드롭다운 열기" },
|
||||
{ "type": "click_if_exists", "target": "매출대금", "description": "매출대금 선택" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "step-12",
|
||||
"name": "저장 및 결과 확인",
|
||||
"description": "저장 버튼 클릭 후 데이터 반영 확인",
|
||||
"click": "저장",
|
||||
"expect": {
|
||||
"toast": "저장 완료 메시지",
|
||||
"url": "/accounting/deposits/{id}",
|
||||
"mode": "view"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-12-1",
|
||||
"name": "⚠️ 필수 검증: 수정 데이터 반영 확인",
|
||||
"note": "토스트 성공 메시지만으로 PASS 판정 불가. 실제 데이터 변경 확인 필수!",
|
||||
"description": "저장 후 상세 페이지에서 변경된 값 확인",
|
||||
"expect": {
|
||||
"fields": [
|
||||
{ "name": "적요", "value": "테스트 적요 수정" },
|
||||
{ "name": "거래처", "value": "거래처테스트" },
|
||||
{ "name": "입금 유형", "value": "매출대금" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-13",
|
||||
"name": "취소 버튼 동작 확인",
|
||||
"description": "수정 모드에서 취소 버튼 동작 검증",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "수정", "description": "수정 모드 진입" },
|
||||
{ "type": "click_if_exists", "target": "취소", "description": "취소 버튼 클릭" }
|
||||
],
|
||||
"expect": {
|
||||
"url": "/accounting/deposits/{id}",
|
||||
"mode": "view",
|
||||
"visible": ["입금 상세", "목록", "삭제", "수정"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-14",
|
||||
"name": "목록 버튼 동작 확인",
|
||||
"description": "목록 버튼 클릭하여 목록 페이지로 이동",
|
||||
"click": "목록",
|
||||
"expect": {
|
||||
"url": "/accounting/deposits",
|
||||
"visible": ["입금관리", "총 입금"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-15",
|
||||
"name": "필터 드롭다운 검증",
|
||||
"description": "목록 페이지 필터 드롭다운 옵션 확인",
|
||||
"note": "3개의 필터 드롭다운 존재 (거래처, 입금유형, 정렬)",
|
||||
"expect": {
|
||||
"filters": [
|
||||
{ "name": "거래처 필터", "default": "전체" },
|
||||
{ "name": "입금유형 필터", "default": "전체" },
|
||||
{ "name": "정렬", "default": "최신순", "options": ["최신순", "등록순", "금액 높은순", "금액 낮은순"] }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-16",
|
||||
"name": "날짜 필터 검증",
|
||||
"description": "날짜 필터 버튼 동작 확인",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "당해년도", "description": "당해년도 버튼 클릭" }
|
||||
],
|
||||
"expect": {
|
||||
"dateRange": {
|
||||
"start": "2026-01-01",
|
||||
"end": "2026-12-31"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-17",
|
||||
"name": "페이지네이션 동작 확인",
|
||||
"description": "페이지네이션 버튼 동작 검증",
|
||||
"expect": {
|
||||
"pagination": {
|
||||
"totalItems": 60,
|
||||
"itemsPerPage": 20,
|
||||
"currentPage": 1,
|
||||
"totalPages": 3
|
||||
}
|
||||
},
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "다음", "description": "다음 페이지로 이동" }
|
||||
],
|
||||
"expectAfterAction": {
|
||||
"currentPage": 2,
|
||||
"displayText": "전체 60개 중 21-40개 표시"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
"deleteTest": {
|
||||
"note": "삭제 테스트 - 이전에 스킵되었으나 CRUD 완전성을 위해 추가",
|
||||
"steps": [
|
||||
{
|
||||
"id": "step-delete-1",
|
||||
"name": "삭제 버튼 클릭",
|
||||
"description": "상세 페이지에서 삭제 버튼 클릭",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "삭제" }
|
||||
],
|
||||
"expect": {
|
||||
"confirmDialog": true,
|
||||
"dialogText": ["삭제", "하시겠습니까"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-delete-2",
|
||||
"name": "삭제 확인",
|
||||
"description": "삭제 확인 다이얼로그에서 확인 클릭",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "확인", "description": "삭제 확인" }
|
||||
],
|
||||
"waitFor": {
|
||||
"type": "navigation",
|
||||
"url": "/accounting/deposits",
|
||||
"timeout": 5000
|
||||
},
|
||||
"expect": {
|
||||
"toast": ["삭제", "완료", "성공"],
|
||||
"url": "/accounting/deposits"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-delete-3",
|
||||
"name": "⚠️ 필수 검증: 삭제 데이터 반영 확인",
|
||||
"note": "토스트 성공 메시지만으로 PASS 판정 불가. 실제 데이터 삭제 확인 필수!",
|
||||
"description": "목록에서 삭제된 입금 내역이 없어졌는지 확인",
|
||||
"verify": {
|
||||
"tableNotContains": "테스트 적요 수정"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"knownBugs": [
|
||||
{
|
||||
"id": "BUG-SALES-20260115-001",
|
||||
"description": "계정과목명 일괄변경 시 토스트 성공 표시되나 실제 데이터 미변경 (매출관리)",
|
||||
"relatedSteps": ["step-4-1"],
|
||||
"note": "입금관리에서도 동일한 버그가 존재할 수 있으므로 step-4-1에서 검증 필수"
|
||||
}
|
||||
],
|
||||
|
||||
"testData": {
|
||||
"sampleDeposit": {
|
||||
"date": "2025-12-28",
|
||||
"account": "운영계좌",
|
||||
"depositor": "CJ대한통운",
|
||||
"amount": "8,209,677",
|
||||
"vendor": "CJ대한통운",
|
||||
"description": "CJ대한통운 입금",
|
||||
"depositType": "미설정"
|
||||
},
|
||||
"modifiedData": {
|
||||
"description": "테스트 적요 수정",
|
||||
"vendor": "거래처테스트",
|
||||
"depositType": "매출대금"
|
||||
}
|
||||
},
|
||||
|
||||
"pageStructure": {
|
||||
"listPage": {
|
||||
"url": "/accounting/deposits",
|
||||
"title": "입금관리",
|
||||
"statistics": ["총 입금", "당월 입금", "거래처 미설정", "입금유형 미설정"],
|
||||
"tableColumns": ["checkbox", "입금일", "입금계좌", "입금자명", "입금금액", "거래처", "적요", "입금유형", "action"],
|
||||
"batchUpdate": {
|
||||
"label": "계정과목명",
|
||||
"saveButton": "저장"
|
||||
},
|
||||
"filters": ["거래처", "입금유형", "정렬"],
|
||||
"dateFilters": ["당해년도", "전전월", "전월", "당월", "어제", "오늘"]
|
||||
},
|
||||
"detailPage": {
|
||||
"url": "/accounting/deposits/{id}",
|
||||
"title": "입금 상세",
|
||||
"buttons": ["목록", "삭제", "수정"],
|
||||
"fields": {
|
||||
"readOnly": ["입금일", "입금계좌", "입금자명", "입금금액"],
|
||||
"editable": ["적요", "거래처", "입금 유형"]
|
||||
}
|
||||
},
|
||||
"editPage": {
|
||||
"url": "/accounting/deposits/{id}?mode=edit",
|
||||
"title": "입금 수정",
|
||||
"buttons": ["취소", "저장"]
|
||||
}
|
||||
},
|
||||
|
||||
"dropdownOptions": {
|
||||
"accountSubject": {
|
||||
"label": "계정과목명",
|
||||
"options": ["미설정", "매출대금", "선수금", "가수금", "임대수익", "이자수익", "보증금 반환", "차입금", "자본금", "부가세 환급", "기타"]
|
||||
},
|
||||
"depositType": {
|
||||
"label": "입금 유형",
|
||||
"options": ["미설정", "매출대금", "선수금", "가수금", "임대수익", "이자수익", "보증금 반환", "차입금", "자본금", "부가세 환급", "기타"]
|
||||
},
|
||||
"vendor": {
|
||||
"label": "거래처",
|
||||
"options": ["거래처테스트", "아크더레드", "코브라브릿지", "가우스전자", "아크아크"]
|
||||
},
|
||||
"sortOrder": {
|
||||
"label": "정렬",
|
||||
"options": ["최신순", "등록순", "금액 높은순", "금액 낮은순"]
|
||||
}
|
||||
},
|
||||
|
||||
"assertions": [
|
||||
{
|
||||
"type": "url",
|
||||
"expected": "/accounting/deposits",
|
||||
"message": "목록 페이지 URL 확인"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"target": "body",
|
||||
"expected": "입금관리",
|
||||
"message": "페이지 타이틀 확인"
|
||||
}
|
||||
]
|
||||
}
|
||||
188
_backup_before_enhance/draft-box.json
Normal file
188
_backup_before_enhance/draft-box.json
Normal file
@@ -0,0 +1,188 @@
|
||||
{
|
||||
"enabled": true,
|
||||
"id": "draft-box",
|
||||
"name": "기안함 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "결재관리 > 기안함 메뉴의 문서 목록 조회, 검색, 필터 기능 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "결재관리",
|
||||
"level2": "기안함",
|
||||
"expectedUrl": "/approval/draft",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 결재관리 > 기안함",
|
||||
"action": "menu_navigate",
|
||||
"level1": "결재관리",
|
||||
"level2": "기안함",
|
||||
"expected": {
|
||||
"url_contains": "/approval/draft",
|
||||
"visible": ["기안함"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"기안함 목록 표시",
|
||||
"검색/필터 기능 존재",
|
||||
"문서 작성 버튼 존재"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "verify_element",
|
||||
"checks": [
|
||||
"진행 카드 표시",
|
||||
"완료 카드 표시",
|
||||
"반려 카드 표시",
|
||||
"임시 저장 카드 표시"
|
||||
],
|
||||
"expected": "통계 카드 4개 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "기안함 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
"문서번호 컬럼",
|
||||
"문서유형 컬럼",
|
||||
"제목 컬럼",
|
||||
"결재자 컬럼",
|
||||
"기안일시 컬럼",
|
||||
"상태 컬럼"
|
||||
],
|
||||
"expected": "기안함 테이블 컬럼 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "데이터 로드 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"기안 문서 데이터 행 존재 또는 '데이터가 없습니다' 메시지"
|
||||
],
|
||||
"expected": "기안 문서 데이터 표시"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"phase": "SEARCH",
|
||||
"name": "[SEARCH] 검색 기능 테스트",
|
||||
"action": "fill",
|
||||
"target": "input[type='search'], input[placeholder*='검색']",
|
||||
"value": "테스트",
|
||||
"submit": true
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "SEARCH",
|
||||
"name": "[SEARCH] 검색 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"검색 결과 표시 또는 결과 없음 메시지"
|
||||
],
|
||||
"expected": "검색 기능 동작"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "SEARCH",
|
||||
"name": "[SEARCH] 검색 초기화",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('초기화'), button:has-text('전체'), button[class*='clear']",
|
||||
"expected": "검색 초기화"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "필터 기능 테스트",
|
||||
"action": "click_if_exists",
|
||||
"target": "select, [role='combobox'], button:has-text('임시저장')",
|
||||
"expected": "필터 옵션 표시"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 문서 상세 보기",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:first-child td:nth-child(2), table tbody tr:first-child",
|
||||
"expected": {
|
||||
"detail_view": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "상세 페이지/모달 확인",
|
||||
"action": "verify_element",
|
||||
"checks": [
|
||||
"문서 상세 정보 표시",
|
||||
"문서번호 또는 제목 표시"
|
||||
],
|
||||
"expected": "상세 정보 표시"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "모달/상세 닫기",
|
||||
"action": "close_modal_if_open",
|
||||
"expected": "모달 닫힘"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"name": "페이지네이션 확인",
|
||||
"action": "verify_element",
|
||||
"checks": [
|
||||
"페이지 번호 또는 이전/다음 버튼"
|
||||
],
|
||||
"expected": "페이지네이션 표시"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"name": "문서 작성 버튼 확인",
|
||||
"action": "verify_element",
|
||||
"checks": [
|
||||
"문서 작성 또는 신규 작성 버튼 존재"
|
||||
],
|
||||
"expected": "문서 작성 버튼 확인"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/approvals/drafts",
|
||||
"description": "기안함 목록 조회"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/approvals/drafts/summary",
|
||||
"description": "기안함 통계 카드"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 3,
|
||||
"name": "검색/필터",
|
||||
"steps": [6, 7, 8],
|
||||
"criteria": "검색 기능 동작"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"criteria": "기안함 목록, 검색 기능, 문서 작성 버튼 존재"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"note": "조회 전용 테스트로 데이터 변경 없음"
|
||||
}
|
||||
}
|
||||
372
_backup_before_enhance/employee-register.json
Normal file
372
_backup_before_enhance/employee-register.json
Normal file
@@ -0,0 +1,372 @@
|
||||
{
|
||||
"id": "employee-register",
|
||||
"name": "직원 등록 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "신규 직원 정보를 입력하고 등록하는 E2E 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"url": "/ko/hr/employee-management",
|
||||
"navigation": {
|
||||
"targetUrl": "/hr/employee-management",
|
||||
"urlPattern": "/hr/employee-management|/ko/hr/employee-management",
|
||||
"menuHints": ["사원관리", "사원 관리", "인사관리"]
|
||||
},
|
||||
"menuNavigation": {
|
||||
"level1": "인사관리",
|
||||
"level2": "사원관리",
|
||||
"expectedUrl": "/ko/hr/employee-management",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"menuNavigationEnhanced": {
|
||||
"strategy": "scroll-and-search",
|
||||
"level1": {
|
||||
"text": "인사관리",
|
||||
"scrollContainer": ".sidebar-scroll, [class*='sidebar'], nav",
|
||||
"maxScrollAttempts": 5,
|
||||
"scrollStep": 200
|
||||
},
|
||||
"level2": {
|
||||
"text": "사원관리",
|
||||
"waitAfterLevel1": 500
|
||||
},
|
||||
"fallbackUrl": "/ko/hr/employee-management",
|
||||
"timeout": 10000
|
||||
},
|
||||
"timeout": 60000,
|
||||
"tags": ["hr", "employee", "crud"],
|
||||
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
|
||||
"steps": [
|
||||
{
|
||||
"id": "step-0",
|
||||
"name": "사이드바 메뉴 전체 펼치기",
|
||||
"description": "모두 펼치기 버튼을 클릭하여 전체 메뉴를 펼친 후 메뉴 탐색 준비",
|
||||
"actions": [
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "document.querySelector('.sidebar-scroll, [class*=\"sidebar\"], nav')?.scrollTo({top: 0, behavior: 'instant'})",
|
||||
"description": "사이드바 스크롤 최상단으로 이동"
|
||||
},
|
||||
{ "type": "wait", "duration": 300 },
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "Array.from(document.querySelectorAll('button')).find(b => b.innerText?.includes('모두 펼치기'))?.click()",
|
||||
"description": "모두 펼치기 버튼 클릭"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 2000,
|
||||
"description": "메뉴 펼침 완료 대기"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "step-1",
|
||||
"name": "인사관리 메뉴 진입",
|
||||
"description": "인사관리 > 직원관리 메뉴로 이동 (scrollAndFind 패턴)",
|
||||
"menuNavigation": {
|
||||
"pattern": "scrollAndFind",
|
||||
"level1": {
|
||||
"text": "인사관리",
|
||||
"scrollContainer": ".sidebar-scroll, [class*='sidebar'], nav",
|
||||
"scrollStep": 200,
|
||||
"maxAttempts": 5
|
||||
},
|
||||
"level2": {
|
||||
"text": "직원관리",
|
||||
"waitAfterLevel1Click": 500
|
||||
}
|
||||
},
|
||||
"expect": {
|
||||
"url": "/hr/employee-management",
|
||||
"visible": ["사원관리", "사원 등록"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-2",
|
||||
"name": "사원 등록 페이지 이동",
|
||||
"click": "사원 등록",
|
||||
"expect": {
|
||||
"url": "/hr/employee-management?mode=new",
|
||||
"visible": ["사원 등록", "사원 정보"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-3",
|
||||
"name": "사원 정보 입력",
|
||||
"description": "기본 사원 정보 입력",
|
||||
"form": {
|
||||
"fields": [
|
||||
{ "name": "이름 *", "type": "text", "value": "홍길동" },
|
||||
{ "name": "주민등록번호", "type": "text", "value": "900101-1234567" },
|
||||
{ "name": "휴대폰", "type": "text", "value": "010-1234-5678" },
|
||||
{ "name": "이메일 *", "type": "text", "value": "test.employee@codebridge-x.com" },
|
||||
{ "name": "연봉", "type": "number", "value": "50000000" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-4",
|
||||
"name": "급여계좌 정보 입력",
|
||||
"form": {
|
||||
"fields": [
|
||||
{ "name": "은행명", "type": "text", "value": "신한은행" },
|
||||
{ "name": "계좌번호", "type": "text", "value": "110-123-456789" },
|
||||
{ "name": "예금주", "type": "text", "value": "홍길동" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-5",
|
||||
"name": "사원 상세 정보 입력",
|
||||
"form": {
|
||||
"fields": [
|
||||
{ "name": "사원코드", "type": "text", "value": "EMP2026001" },
|
||||
{ "name": "남성", "type": "radio", "value": "true" },
|
||||
{ "name": "상세주소를 입력해주세요", "type": "text", "value": "123번지 4층" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-6",
|
||||
"name": "인사 정보 입력",
|
||||
"form": {
|
||||
"fields": [
|
||||
{ "name": "입사일", "type": "date", "value": "2026-01-14" }
|
||||
]
|
||||
},
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "고용형태 선택", "description": "고용형태 드롭다운 열기" },
|
||||
{ "type": "click_if_exists", "target": "정규직", "description": "정규직 선택" },
|
||||
{ "type": "click_if_exists", "target": "직급 선택", "description": "직급 드롭다운 열기" },
|
||||
{ "type": "click_if_exists", "target": "사원", "description": "사원 직급 선택" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "step-7",
|
||||
"name": "사용자 정보 입력",
|
||||
"form": {
|
||||
"fields": [
|
||||
{ "name": "아이디 *", "type": "text", "value": "testuser2026" },
|
||||
{ "name": "비밀번호 *", "type": "text", "value": "password123!" },
|
||||
{ "name": "비밀번호 확인 *", "type": "text", "value": "password123!" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-8",
|
||||
"name": "등록 완료",
|
||||
"click": "등록",
|
||||
"waitFor": "사원관리",
|
||||
"expect": {
|
||||
"url": "/hr/employee-management",
|
||||
"text": ["홍길동"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-8-1",
|
||||
"name": "검색 기간 설정 - 유효 기간",
|
||||
"description": "등록된 사원의 입사일(2026-01-14)이 포함되는 기간으로 검색",
|
||||
"actions": [
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "input[placeholder*='시작'], input[name*='startDate'], input[type='date']:first-of-type"
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "input[placeholder*='종료'], input[name*='endDate'], input[type='date']:last-of-type"
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "button:has-text('검색'), .search-btn, [type='submit']"
|
||||
}
|
||||
],
|
||||
"expect": {
|
||||
"tableContains": "홍길동",
|
||||
"rowCount": ">= 1"
|
||||
},
|
||||
"onFail": {
|
||||
"record": true,
|
||||
"message": "검색 기간 2026-01-01 ~ 2026-01-31 내 입사일(2026-01-14) 사원이 검색되지 않음",
|
||||
"severity": "HIGH",
|
||||
"bugType": "검색 기간 필터링 오류"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-8-2",
|
||||
"name": "검색 기간 설정 - 범위 외 기간",
|
||||
"description": "등록된 사원의 입사일이 포함되지 않는 기간으로 검색하여 검색되지 않음을 확인",
|
||||
"actions": [
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "input[placeholder*='시작'], input[name*='startDate'], input[type='date']:first-of-type"
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "input[placeholder*='종료'], input[name*='endDate'], input[type='date']:last-of-type"
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "button:has-text('검색'), .search-btn, [type='submit']"
|
||||
}
|
||||
],
|
||||
"expect": {
|
||||
"tableNotContains": "홍길동",
|
||||
"alternativeExpect": {
|
||||
"emptyResult": true,
|
||||
"message": "검색 결과 없음"
|
||||
}
|
||||
},
|
||||
"verify": {
|
||||
"searchPeriodValidation": {
|
||||
"inputPeriod": "2025-01-01 ~ 2025-12-31",
|
||||
"employeeJoinDate": "2026-01-14",
|
||||
"expectedResult": "NOT_FOUND",
|
||||
"actualResultCheck": true
|
||||
}
|
||||
},
|
||||
"onFail": {
|
||||
"record": true,
|
||||
"message": "검색 기간 2025-01-01 ~ 2025-12-31 범위 외 입사일(2026-01-14) 사원이 검색됨 - 기간 필터 미작동",
|
||||
"severity": "HIGH",
|
||||
"bugType": "검색 기간 필터링 미작동"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-8-3",
|
||||
"name": "검색 기간 초기화 및 전체 조회",
|
||||
"description": "검색 조건 초기화하여 등록된 사원이 다시 표시되는지 확인",
|
||||
"actions": [
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "초기화",
|
||||
"fallbackSelectors": ["button:has-text('초기화')", ".reset-btn", "button:has-text('Reset')"]
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "검색",
|
||||
"fallbackSelectors": ["button:has-text('검색')", ".search-btn"]
|
||||
}
|
||||
],
|
||||
"expect": {
|
||||
"tableContains": "홍길동"
|
||||
},
|
||||
"onFail": {
|
||||
"record": true,
|
||||
"message": "검색 초기화 후 전체 조회에서 등록된 사원이 표시되지 않음",
|
||||
"severity": "MEDIUM",
|
||||
"bugType": "검색 초기화 오류"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-9",
|
||||
"name": "등록된 직원 상세 페이지 이동",
|
||||
"description": "등록된 직원을 클릭하여 상세 페이지로 이동",
|
||||
"actions": [
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "table tbody tr:has-text('홍길동')",
|
||||
"description": "해당 행 클릭하여 상세 페이지 이동"
|
||||
}
|
||||
],
|
||||
"expect": {
|
||||
"url": "/hr/employee-management/{id}",
|
||||
"visible": ["사원 상세", "수정", "삭제", "목록"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-10",
|
||||
"name": "직원 수정 모드 전환",
|
||||
"description": "수정 버튼 클릭하여 편집 모드로 전환",
|
||||
"click": "수정",
|
||||
"expect": {
|
||||
"url": "/hr/employee-management/{id}?mode=edit",
|
||||
"visible": ["사원 수정", "취소", "저장"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-11",
|
||||
"name": "직원 정보 수정",
|
||||
"description": "휴대폰 번호 변경",
|
||||
"form": {
|
||||
"fields": [
|
||||
{ "name": "휴대폰", "type": "text", "value": "010-9999-8888", "clear": true }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-12",
|
||||
"name": "수정 저장",
|
||||
"description": "수정된 직원 정보 저장",
|
||||
"click": "저장",
|
||||
"waitFor": "사원 상세",
|
||||
"expect": {
|
||||
"toast": ["수정", "완료", "성공", "저장"],
|
||||
"url": "/hr/employee-management/{id}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-12-1",
|
||||
"name": "⚠️ 필수 검증: 수정 데이터 반영 확인",
|
||||
"note": "토스트 성공 메시지만으로 PASS 판정 불가. 실제 데이터 변경 확인 필수!",
|
||||
"description": "상세 페이지에서 수정된 휴대폰 번호 확인",
|
||||
"verify": {
|
||||
"fieldValue": {
|
||||
"target": "휴대폰",
|
||||
"expected": "010-9999-8888"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-13",
|
||||
"name": "직원 삭제",
|
||||
"description": "삭제 버튼 클릭하여 직원 삭제",
|
||||
"click": "삭제",
|
||||
"expect": {
|
||||
"confirmDialog": true,
|
||||
"dialogText": ["삭제", "하시겠습니까"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-14",
|
||||
"name": "삭제 확인",
|
||||
"description": "삭제 확인 다이얼로그에서 확인 클릭",
|
||||
"click": "확인",
|
||||
"waitFor": "사원관리",
|
||||
"expect": {
|
||||
"toast": ["삭제", "완료", "성공"],
|
||||
"url": "/hr/employee-management"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-15",
|
||||
"name": "⚠️ 필수 검증: 삭제 데이터 반영 확인",
|
||||
"note": "토스트 성공 메시지만으로 PASS 판정 불가. 실제 데이터 삭제 확인 필수!",
|
||||
"description": "목록에서 삭제된 직원이 없어졌는지 확인",
|
||||
"verify": {
|
||||
"tableNotContains": "홍길동"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
"assertions": [
|
||||
{
|
||||
"type": "url",
|
||||
"expected": "/hr/employee-management",
|
||||
"message": "등록 후 직원 목록 페이지로 이동해야 함"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"target": "body",
|
||||
"expected": "홍길동",
|
||||
"message": "등록된 직원이 목록에 표시되어야 함"
|
||||
}
|
||||
]
|
||||
}
|
||||
82
_backup_before_enhance/free-board.json
Normal file
82
_backup_before_enhance/free-board.json
Normal file
@@ -0,0 +1,82 @@
|
||||
{
|
||||
"enabled": true,
|
||||
"id": "free-board",
|
||||
"name": "자유게시판 E2E 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "자유게시판 목록/검색/상세 기능 검증",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "게시판",
|
||||
"level2": "자유게시판",
|
||||
"expectedUrl": "/boards/free",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 게시판 > 자유게시판",
|
||||
"action": "menu_navigate",
|
||||
"level1": "게시판",
|
||||
"level2": "자유게시판",
|
||||
"expected": { "url_contains": "/boards/free" }
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "목업 감지",
|
||||
"action": "verify_not_mockup"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "자유게시판 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:게시판"]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "테이블 확인",
|
||||
"action": "verify_table"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "검색 기능",
|
||||
"action": "search",
|
||||
"value": "테스트"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "검색 후 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:게시판"]
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "첫 번째 행 클릭",
|
||||
"action": "click_first_row"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "상세 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:게시"]
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "모달 닫기",
|
||||
"action": "close_modal_if_open"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "목록 복귀",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('목록'), a:has-text('목록')"
|
||||
}
|
||||
]
|
||||
}
|
||||
83
_backup_before_enhance/hr-attendance-admin.json
Normal file
83
_backup_before_enhance/hr-attendance-admin.json
Normal file
@@ -0,0 +1,83 @@
|
||||
{
|
||||
"id": "hr-attendance-admin",
|
||||
"name": "근태관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "인사관리 > 근태관리 목록/상세 기능 검증",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "인사관리",
|
||||
"level2": "근태관리",
|
||||
"expectedUrl": "/hr/attendance-management",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 인사관리 > 근태관리",
|
||||
"action": "menu_navigate",
|
||||
"level1": "인사관리",
|
||||
"level2": "근태관리",
|
||||
"expected": { "url_contains": "/hr/attendance" }
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "목업 감지",
|
||||
"action": "verify_not_mockup"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "근태관리 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:근태"]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "UI 요소 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:관리"]
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "필터/검색 시도",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[type='search'], input[type='date'], input[placeholder*='검색'], input[placeholder*='조회'], [class*='search'] input, [class*='filter'] input"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "대기",
|
||||
"action": "wait",
|
||||
"duration": 1000
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "행 클릭 시도",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr, [role='row']:not(:first-child), [class*='list'] [class*='item']"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "상세 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:근태"]
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "모달 닫기",
|
||||
"action": "close_modal_if_open"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "최종 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:근태"]
|
||||
}
|
||||
]
|
||||
}
|
||||
211
_backup_before_enhance/hr-attendance-status.json
Normal file
211
_backup_before_enhance/hr-attendance-status.json
Normal file
@@ -0,0 +1,211 @@
|
||||
{
|
||||
"id": "hr-attendance-status",
|
||||
"name": "근태현황 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "인사관리 > 근태현황 메뉴의 출퇴근 현황 조회/필터/출퇴근 기능 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "인사관리",
|
||||
"level2": "근태현황",
|
||||
"expectedUrl": "/hr/attendance",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 인사관리 > 근태현황",
|
||||
"action": "menu_navigate",
|
||||
"level1": "인사관리",
|
||||
"level2": "근태현황",
|
||||
"expected": {
|
||||
"url_contains": "/hr/attendance",
|
||||
"visible": ["근태현황", "출근", "퇴근"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"출퇴근 현황 표시",
|
||||
"날짜 선택 가능",
|
||||
"출근/퇴근 버튼 존재"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "근태 현황 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
"날짜 컬럼",
|
||||
"출근시간 컬럼",
|
||||
"퇴근시간 컬럼",
|
||||
"근무시간 컬럼",
|
||||
"상태 컬럼"
|
||||
],
|
||||
"expected": "근태 현황 테이블 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "오늘 근태 상태 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"오늘 날짜 표시",
|
||||
"현재 근무 상태 표시"
|
||||
],
|
||||
"expected": "오늘 근태 상태 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "출근 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"출근 버튼 존재"
|
||||
],
|
||||
"expected": "출근 버튼 표시"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "퇴근 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"퇴근 버튼 존재"
|
||||
],
|
||||
"expected": "퇴근 버튼 표시"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 기간 필터 - 월 선택",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[type='month'], select[name*='month'], [class*='month-picker']",
|
||||
"expected": "월 선택 열림"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 조회 적용",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('조회'), button:has-text('검색'), button:has-text('적용')",
|
||||
"expected": "필터 적용됨"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 필터 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"선택한 월의 근태 데이터 표시"
|
||||
],
|
||||
"expected": "필터 동작 확인"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "근무 시간 통계 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"총 근무시간 표시",
|
||||
"정상 출근 일수 표시"
|
||||
],
|
||||
"expected": "근무 통계 표시"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "지각/조퇴/결근 통계 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"지각 횟수 표시",
|
||||
"조퇴 횟수 표시",
|
||||
"결근 횟수 표시"
|
||||
],
|
||||
"expected": "근태 이상 통계 표시"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 특정 일자 상세 보기",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:first-child",
|
||||
"expected": {
|
||||
"detail_view": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"name": "상세 근태 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"출근 시간 표시",
|
||||
"퇴근 시간 표시",
|
||||
"근무 시간 표시"
|
||||
],
|
||||
"expected": "상세 근태 정보 표시"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"name": "엑셀 다운로드 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"엑셀 다운로드 버튼 존재"
|
||||
],
|
||||
"expected": "엑셀 다운로드 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"name": "인쇄 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"인쇄 버튼 존재"
|
||||
],
|
||||
"expected": "인쇄 기능 표시"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/hr/attendance",
|
||||
"description": "근태 현황 조회"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"endpoint": "/api/v1/hr/attendance/check-in",
|
||||
"description": "출근 체크"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"endpoint": "/api/v1/hr/attendance/check-out",
|
||||
"description": "퇴근 체크"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/hr/attendance/summary",
|
||||
"description": "근태 통계 조회"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 3,
|
||||
"name": "검색/필터",
|
||||
"steps": [7, 8, 9],
|
||||
"criteria": "기간 필터 동작"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"criteria": "근태 현황, 날짜 선택, 출퇴근 버튼 존재"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"note": "조회 전용 페이지로 데이터 변경 없음 (출퇴근 체크는 별도 테스트)"
|
||||
}
|
||||
}
|
||||
81
_backup_before_enhance/hr-card.json
Normal file
81
_backup_before_enhance/hr-card.json
Normal file
@@ -0,0 +1,81 @@
|
||||
{
|
||||
"id": "hr-card",
|
||||
"name": "카드관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "인사관리 > 카드관리 목록/검색/상세 기능 검증",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "인사관리",
|
||||
"level2": "카드관리",
|
||||
"expectedUrl": "/hr/card-management",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 인사관리 > 카드관리",
|
||||
"action": "menu_navigate",
|
||||
"level1": "인사관리",
|
||||
"level2": "카드관리",
|
||||
"expected": { "url_contains": "/hr/card" }
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "목업 감지",
|
||||
"action": "verify_not_mockup"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "카드관리 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:카드"]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "테이블 확인",
|
||||
"action": "verify_table"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "검색 기능",
|
||||
"action": "search",
|
||||
"value": "테스트"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "검색 후 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:카드"]
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "첫 번째 행 클릭",
|
||||
"action": "click_first_row"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "상세 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:카드"]
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "모달 닫기",
|
||||
"action": "close_modal_if_open"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "목록 복귀",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('목록'), a:has-text('목록')"
|
||||
}
|
||||
]
|
||||
}
|
||||
83
_backup_before_enhance/hr-department.json
Normal file
83
_backup_before_enhance/hr-department.json
Normal file
@@ -0,0 +1,83 @@
|
||||
{
|
||||
"id": "hr-department",
|
||||
"name": "부서관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "인사관리 > 부서관리 목록/상세 기능 검증",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "인사관리",
|
||||
"level2": "부서관리",
|
||||
"expectedUrl": "/hr/department-management",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 인사관리 > 부서관리",
|
||||
"action": "menu_navigate",
|
||||
"level1": "인사관리",
|
||||
"level2": "부서관리",
|
||||
"expected": { "url_contains": "/hr/department" }
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "목업 감지",
|
||||
"action": "verify_not_mockup"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "부서관리 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:부서"]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "UI 요소 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:관리"]
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "검색 입력 시도",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[type='search'], input[placeholder*='검색'], input[placeholder*='조회'], [class*='search'] input"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "대기",
|
||||
"action": "wait",
|
||||
"duration": 1000
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "행 클릭 시도",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr, [role='row']:not(:first-child), [class*='list'] [class*='item']"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "상세 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:부서"]
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "모달 닫기",
|
||||
"action": "close_modal_if_open"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "최종 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:부서"]
|
||||
}
|
||||
]
|
||||
}
|
||||
81
_backup_before_enhance/hr-employee.json
Normal file
81
_backup_before_enhance/hr-employee.json
Normal file
@@ -0,0 +1,81 @@
|
||||
{
|
||||
"id": "hr-employee",
|
||||
"name": "사원관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "인사관리 > 사원관리 목록/검색/상세 기능 검증",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "인사관리",
|
||||
"level2": "사원관리",
|
||||
"expectedUrl": "/hr/employee-management",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 인사관리 > 사원관리",
|
||||
"action": "menu_navigate",
|
||||
"level1": "인사관리",
|
||||
"level2": "사원관리",
|
||||
"expected": { "url_contains": "/hr/employee" }
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "목업 감지",
|
||||
"action": "verify_not_mockup"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "사원관리 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:사원"]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "테이블 확인",
|
||||
"action": "verify_table"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "검색 기능",
|
||||
"action": "search",
|
||||
"value": "테스트"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "검색 후 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:사원"]
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "첫 번째 행 클릭",
|
||||
"action": "click_first_row"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "상세 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:사원"]
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "모달 닫기",
|
||||
"action": "close_modal_if_open"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "목록 복귀",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('목록'), a:has-text('목록')"
|
||||
}
|
||||
]
|
||||
}
|
||||
81
_backup_before_enhance/hr-salary.json
Normal file
81
_backup_before_enhance/hr-salary.json
Normal file
@@ -0,0 +1,81 @@
|
||||
{
|
||||
"id": "hr-salary",
|
||||
"name": "급여관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "인사관리 > 급여관리 목록/검색/상세 기능 검증",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "인사관리",
|
||||
"level2": "급여관리",
|
||||
"expectedUrl": "/hr/salary-management",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 인사관리 > 급여관리",
|
||||
"action": "menu_navigate",
|
||||
"level1": "인사관리",
|
||||
"level2": "급여관리",
|
||||
"expected": { "url_contains": "/hr/salary" }
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "목업 감지",
|
||||
"action": "verify_not_mockup"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "급여관리 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:급여"]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "테이블 확인",
|
||||
"action": "verify_table"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "검색 기능",
|
||||
"action": "search",
|
||||
"value": "테스트"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "검색 후 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:급여"]
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "첫 번째 행 클릭",
|
||||
"action": "click_first_row"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "상세 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:급여"]
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "모달 닫기",
|
||||
"action": "close_modal_if_open"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "목록 복귀",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('목록'), a:has-text('목록')"
|
||||
}
|
||||
]
|
||||
}
|
||||
352
_backup_before_enhance/hr-vacation.json
Normal file
352
_backup_before_enhance/hr-vacation.json
Normal file
@@ -0,0 +1,352 @@
|
||||
{
|
||||
"id": "hr-vacation",
|
||||
"name": "휴가관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": [
|
||||
"error",
|
||||
"fail",
|
||||
"timeout",
|
||||
"404",
|
||||
"500",
|
||||
"blocked"
|
||||
]
|
||||
},
|
||||
"description": "인사관리 > 휴가관리 메뉴의 휴가 신청/조회/수정/취소 전체 CRUD 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "인사관리",
|
||||
"level2": "휴가관리",
|
||||
"expectedUrl": "/hr/vacation-management",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"testData": {
|
||||
"create": {
|
||||
"vacationType": "연차",
|
||||
"startDate": "2026-02-10",
|
||||
"endDate": "2026-02-10",
|
||||
"reason": "E2E 자동화 테스트 휴가 신청"
|
||||
},
|
||||
"update": {
|
||||
"reason": "E2E 수정된 휴가 사유"
|
||||
}
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 인사관리 > 휴가관리",
|
||||
"action": "menu_navigate",
|
||||
"level1": "인사관리",
|
||||
"level2": "휴가관리",
|
||||
"expected": {
|
||||
"url_contains": "/hr/vacation",
|
||||
"visible": [
|
||||
"휴가관리",
|
||||
"휴가"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"휴가 목록 표시",
|
||||
"휴가 신청 버튼 존재",
|
||||
"연차 현황 표시"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "휴가 현황 카드 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"잔여 연차 표시",
|
||||
"사용 연차 표시",
|
||||
"총 연차 표시"
|
||||
],
|
||||
"expected": "휴가 현황 카드 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "휴가 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
"휴가 유형 컬럼",
|
||||
"시작일 컬럼",
|
||||
"종료일 컬럼",
|
||||
"상태 컬럼",
|
||||
"신청일 컬럼"
|
||||
],
|
||||
"expected": "휴가 테이블 컬럼 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 휴가 신청 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('신청'), button:has-text('휴가 신청'), button:has-text('추가')",
|
||||
"expected": {
|
||||
"modal": true,
|
||||
"modalTitle": "휴가 신청"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 휴가 정보 입력",
|
||||
"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}"
|
||||
}
|
||||
],
|
||||
"note": "타임스탬프로 고유성 보장",
|
||||
"target": "form, [role='dialog'], .modal"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 필수 검증 #2: 신청 저장",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('신청'), button:has-text('저장'), button:has-text('확인')",
|
||||
"verify": {
|
||||
"url_maintained": true,
|
||||
"no_error_page": true,
|
||||
"api_call": "POST /api/v1/vacations",
|
||||
"toast": "신청|등록|완료|성공"
|
||||
},
|
||||
"expected": "휴가 신청 완료"
|
||||
},
|
||||
{
|
||||
"id": "7-modal-close",
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 모달 닫기 확인",
|
||||
"action": "close_modal_if_open",
|
||||
"expected": "모달 닫힘"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 신청 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"search": "E2E 자동화 테스트 휴가",
|
||||
"expected": {
|
||||
"row_exists": true,
|
||||
"contains": [
|
||||
"연차",
|
||||
"대기",
|
||||
"2026-02-10"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 휴가 상세 페이지 진입",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:has-text('E2E')",
|
||||
"expected": {
|
||||
"url_contains": "/hr/vacation",
|
||||
"visible": [
|
||||
"휴가 상세",
|
||||
"수정",
|
||||
"취소"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"휴가 유형: 연차",
|
||||
"시작일: 2026-02-10",
|
||||
"종료일: 2026-02-10",
|
||||
"상태: 대기",
|
||||
"사유: E2E 자동화 테스트"
|
||||
],
|
||||
"expected": "입력한 데이터와 일치"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 모드 진입",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('수정')",
|
||||
"expected": {
|
||||
"modal_or_edit_mode": true,
|
||||
"fields_editable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 사유 수정",
|
||||
"action": "click_if_exists",
|
||||
"target": "textarea[name*='reason'], input[placeholder*='사유']",
|
||||
"value": "E2E 수정된 휴가 사유_{timestamp}",
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 필수 검증 #2: 수정 저장",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('저장'), button:has-text('수정')",
|
||||
"verify": {
|
||||
"url_maintained": true,
|
||||
"no_error_page": true,
|
||||
"api_call": "PUT /api/v1/vacations/",
|
||||
"toast": "수정|완료|성공"
|
||||
},
|
||||
"expected": "수정 완료"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"사유: E2E 수정된 휴가"
|
||||
],
|
||||
"expected": "수정된 데이터 반영"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 취소 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('취소'), button:has-text('신청 취소')",
|
||||
"expected": {
|
||||
"confirm_dialog": true,
|
||||
"dialog_message": "취소|정말"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 필수 검증 #6: 취소 확인",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('확인'), button:has-text('예')",
|
||||
"verify": {
|
||||
"api_call": "DELETE /api/v1/vacations/",
|
||||
"toast": "취소|삭제|완료|성공",
|
||||
"redirect": "/hr/vacation"
|
||||
},
|
||||
"expected": "휴가 취소 완료 및 목록 복귀"
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 취소 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"search": "E2E 수정된 휴가",
|
||||
"expected": {
|
||||
"row_exists": false,
|
||||
"message": "테스트 휴가 신청이 목록에서 제거됨"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"phase": "VERIFY",
|
||||
"name": "[VERIFY] 연차 잔여일 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"잔여 연차가 원래 값으로 복원"
|
||||
],
|
||||
"expected": "휴가 취소 후 연차 복원 확인"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/vacations",
|
||||
"description": "휴가 목록 조회"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/vacations/summary",
|
||||
"description": "휴가 현황 조회"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"endpoint": "/api/v1/vacations",
|
||||
"description": "휴가 신청"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/vacations/{id}",
|
||||
"description": "휴가 상세 조회"
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"endpoint": "/api/v1/vacations/{id}",
|
||||
"description": "휴가 수정"
|
||||
},
|
||||
{
|
||||
"method": "DELETE",
|
||||
"endpoint": "/api/v1/vacations/{id}",
|
||||
"description": "휴가 취소"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 2,
|
||||
"name": "등록/저장 버튼",
|
||||
"steps": [
|
||||
7,
|
||||
13
|
||||
],
|
||||
"criteria": "API 호출 + 성공 토스트 + 데이터 반영"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [
|
||||
2
|
||||
],
|
||||
"criteria": "휴가 목록, 신청 버튼, 현황 카드 존재"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "삭제 기능",
|
||||
"steps": [
|
||||
15,
|
||||
16,
|
||||
17
|
||||
],
|
||||
"criteria": "DELETE API + 목록에서 제거 + 연차 복원"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"onCreateFail": "모달 닫기 → 다음 테스트 영향 없음",
|
||||
"onUpdateFail": "테스트 휴가 수동 취소 필요",
|
||||
"onDeleteFail": "테스트 휴가 수동 취소 필요",
|
||||
"cleanupRequired": "E2E_ 접두사 휴가 신청은 테스트 데이터"
|
||||
}
|
||||
}
|
||||
250
_backup_before_enhance/inventory-status.json
Normal file
250
_backup_before_enhance/inventory-status.json
Normal file
@@ -0,0 +1,250 @@
|
||||
{
|
||||
"id": "inventory-status",
|
||||
"name": "재고현황 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "자재관리 > 재고현황 페이지의 재고 조회 및 엑셀 다운로드 기능을 테스트하는 E2E 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"url": "/material/stock-status",
|
||||
"navigation": {
|
||||
"targetUrl": "/material/stock-status",
|
||||
"urlPattern": "/material/stock-status|/ko/material/stock-status",
|
||||
"menuHints": ["재고현황", "재고 현황", "자재관리"]
|
||||
},
|
||||
"menuNavigation": {
|
||||
"level1": "자재관리",
|
||||
"level2": "재고현황",
|
||||
"expectedUrl": "/material/stock-status",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"menuNavigationEnhanced": {
|
||||
"strategy": "scroll-and-search",
|
||||
"sidebar": {
|
||||
"scrollContainer": ".sidebar-scroll",
|
||||
"scrollStep": 200,
|
||||
"maxScrollAttempts": 5,
|
||||
"waitAfterScroll": 300
|
||||
},
|
||||
"level1": {
|
||||
"text": "자재관리",
|
||||
"expandable": true,
|
||||
"waitAfterClick": 500
|
||||
},
|
||||
"level2": {
|
||||
"text": "재고현황",
|
||||
"waitAfterClick": 300
|
||||
},
|
||||
"fallbackUrl": "/material/stock-status",
|
||||
"expectedUrl": "/material/stock-status"
|
||||
},
|
||||
"timeout": 90000,
|
||||
"tags": ["material", "inventory", "read-only"],
|
||||
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
|
||||
"steps": [
|
||||
{
|
||||
"id": "step-0",
|
||||
"name": "사이드바 메뉴 전체 펼치기",
|
||||
"description": "모두 펼치기 버튼을 클릭하여 전체 메뉴를 펼친 후 메뉴 탐색 준비",
|
||||
"actions": [
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "document.querySelector('.sidebar-scroll')?.scrollTo({top:0,behavior:'instant'})"
|
||||
},
|
||||
{ "type": "wait", "duration": 300 },
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "Array.from(document.querySelectorAll('button')).find(b => b.innerText?.includes('모두 펼치기'))?.click()"
|
||||
},
|
||||
{ "type": "wait", "duration": 2000 }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "step-1",
|
||||
"name": "자재관리 메뉴 진입",
|
||||
"description": "자재관리 > 재고현황 메뉴로 이동",
|
||||
"actions": [
|
||||
{
|
||||
"type": "scrollAndFind",
|
||||
"container": ".sidebar-scroll",
|
||||
"target": "자재관리",
|
||||
"scrollStep": 200,
|
||||
"maxAttempts": 5
|
||||
},
|
||||
{ "type": "click_if_exists", "target": "자재관리" },
|
||||
{ "type": "wait", "duration": 500 },
|
||||
{ "type": "click_if_exists", "target": "재고현황" }
|
||||
],
|
||||
"expect": {
|
||||
"url": "/material/stock-status",
|
||||
"visible": ["재고 목록", "엑셀 다운로드"]
|
||||
},
|
||||
"fallback": {
|
||||
"type": "navigate",
|
||||
"url": "/material/stock-status"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-2",
|
||||
"name": "페이지 구조 확인",
|
||||
"description": "통계 카드와 테이블 구조 확인",
|
||||
"verify": {
|
||||
"visible": ["전체 품목", "정상 재고", "재고 부족", "재고 없음"],
|
||||
"tableColumns": ["번호", "품목코드", "품목명", "품목유형", "단위", "재고량", "안전재고", "LOT", "상태", "위치"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-3",
|
||||
"name": "필수 검증 #3: 품목유형 탭 필터 - 원자재",
|
||||
"description": "원자재 탭 클릭하여 필터링 확인",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "원자재", "role": "tab" },
|
||||
{ "type": "wait", "duration": 500 }
|
||||
],
|
||||
"expect": {
|
||||
"tabActive": "원자재",
|
||||
"dataFiltered": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-4",
|
||||
"name": "필수 검증 #3: 품목유형 탭 필터 - 부자재",
|
||||
"description": "부자재 탭 클릭하여 필터링 확인",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "부자재", "role": "tab" },
|
||||
{ "type": "wait", "duration": 500 }
|
||||
],
|
||||
"expect": {
|
||||
"tabActive": "부자재",
|
||||
"dataFiltered": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-5",
|
||||
"name": "필수 검증 #3: 품목유형 탭 필터 - 소모품",
|
||||
"description": "소모품 탭 클릭하여 필터링 확인",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "소모품", "role": "tab" },
|
||||
{ "type": "wait", "duration": 500 }
|
||||
],
|
||||
"expect": {
|
||||
"tabActive": "소모품",
|
||||
"dataFiltered": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-6",
|
||||
"name": "전체 탭으로 복귀",
|
||||
"description": "전체 탭 클릭하여 모든 재고 표시",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "전체", "role": "tab" },
|
||||
{ "type": "wait", "duration": 300 }
|
||||
],
|
||||
"expect": {
|
||||
"tabActive": "전체",
|
||||
"allDataShown": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-7",
|
||||
"name": "필수 검증 #1: 엑셀 다운로드",
|
||||
"description": "엑셀 다운로드 버튼 동작 확인",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "엑셀 다운로드" },
|
||||
{ "type": "wait", "duration": 1000 }
|
||||
],
|
||||
"expect": {
|
||||
"downloadTriggered": true,
|
||||
"noErrorPage": true
|
||||
},
|
||||
"verify": {
|
||||
"apiCall": "GET /api/material/stock-status/export"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-8",
|
||||
"name": "재고 상세 열기",
|
||||
"description": "재고 항목 클릭하여 상세 보기",
|
||||
"actions": [
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "document.querySelector('tbody tr')?.click()"
|
||||
}
|
||||
],
|
||||
"expect": {
|
||||
"pageOrModal": "재고 상세",
|
||||
"visible": ["품목코드", "품목명", "재고량", "LOT"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-9",
|
||||
"name": "상세 닫기",
|
||||
"description": "ESC 키로 상세 닫기 또는 뒤로가기",
|
||||
"actions": [
|
||||
{ "type": "press", "key": "Escape" },
|
||||
{ "type": "wait", "duration": 300 }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "step-10",
|
||||
"name": "페이지네이션 확인",
|
||||
"description": "페이지네이션 동작 확인",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "다음" },
|
||||
{ "type": "wait", "duration": 500 }
|
||||
],
|
||||
"expect": {
|
||||
"pageChanged": true
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
"assertions": [
|
||||
{
|
||||
"type": "url",
|
||||
"expected": "/material/stock-status",
|
||||
"message": "재고현황 페이지에 머물러야 함"
|
||||
},
|
||||
{
|
||||
"type": "elementExists",
|
||||
"selector": "button:has-text('엑셀 다운로드')",
|
||||
"message": "엑셀 다운로드 버튼이 표시되어야 함"
|
||||
}
|
||||
],
|
||||
|
||||
"mandatoryVerifications": {
|
||||
"description": "E2E_TEST_CONFIG.md 기준 필수 검증 항목",
|
||||
"items": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "파일 다운로드",
|
||||
"trigger": "엑셀 다운로드 버튼",
|
||||
"verification": "Network API + 실제 다운로드 확인",
|
||||
"failCondition": "Console LOG만으로 PASS 금지"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "검색/필터",
|
||||
"trigger": "품목유형 탭 필터",
|
||||
"verification": "데이터 변화 확인",
|
||||
"failCondition": "필터 적용 후 데이터 무변화"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"notes": {
|
||||
"testScope": "재고현황 조회 및 필터링, 엑셀 다운로드 테스트",
|
||||
"pageType": "조회 전용 (입고관리에서 재고 증가, 출하관리에서 재고 감소)",
|
||||
"statsCards": ["전체 품목", "정상 재고", "재고 부족", "재고 없음"],
|
||||
"typeTabs": ["전체", "원자재", "부자재", "소모품"],
|
||||
"tableColumns": ["번호", "품목코드", "품목명", "품목유형", "단위", "재고량", "안전재고", "LOT", "상태", "위치"],
|
||||
"prerequisites": "로그인된 사용자"
|
||||
}
|
||||
}
|
||||
150
_backup_before_enhance/item-management.json
Normal file
150
_backup_before_enhance/item-management.json
Normal file
@@ -0,0 +1,150 @@
|
||||
{
|
||||
"id": "item-management",
|
||||
"name": "품목관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "생산관리 > 품목관리 메뉴의 품목 목록 조회 및 UI 검증 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "생산관리",
|
||||
"level2": "품목관리",
|
||||
"expectedUrl": "/production/screen-production",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 생산관리 > 품목관리",
|
||||
"action": "menu_navigate",
|
||||
"level1": "생산관리",
|
||||
"level2": "품목관리",
|
||||
"expected": {
|
||||
"url_contains": "/production",
|
||||
"visible": ["품목관리", "품목"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"품목 목록 또는 통계 카드 표시",
|
||||
"품목 등록 버튼 존재",
|
||||
"검색 기능 존재"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "품목 UI 구조 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"통계 카드 영역",
|
||||
"품목 목록 테이블",
|
||||
"검색 입력 필드",
|
||||
"탭/필터 버튼"
|
||||
],
|
||||
"expected": "품목관리 UI 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
"품목코드 컬럼",
|
||||
"품목명 컬럼",
|
||||
"규격 컬럼"
|
||||
],
|
||||
"expected": "품목 테이블 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 품목 목록 데이터 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"품목 목록 데이터 표시됨"
|
||||
],
|
||||
"expected": "품목 목록 정상"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 첫 번째 행 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:first-child, button:has-text('상세')"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 품목 상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"품목 상세 정보 표시"
|
||||
],
|
||||
"expected": "품목 상세 정보 확인"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "상세 모달/페이지 닫기",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('닫기'), button:has-text('Close'), button:has-text('목록'), [class*='close']"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "모달 닫기 확인",
|
||||
"action": "close_modal_if_open",
|
||||
"expected": "모달 닫힘"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "탭/필터 기능 확인",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('전체'), [class*='tab']:has-text('전체')"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "등록 버튼 존재 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"품목 등록 버튼 존재"
|
||||
],
|
||||
"expected": "등록 버튼 표시"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "품목관리 페이지 최종 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"품목 목록 구조 정상",
|
||||
"통계 카드 또는 요약 정보 표시"
|
||||
],
|
||||
"expected": "품목관리 페이지 정상"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/items",
|
||||
"description": "품목 목록 조회"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"criteria": "품목 목록, 등록 버튼, 검색 기능 존재"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"note": "READ-only 패턴으로 안정성 우선, 비표준 포맷 제거"
|
||||
}
|
||||
}
|
||||
83
_backup_before_enhance/item-master.json
Normal file
83
_backup_before_enhance/item-master.json
Normal file
@@ -0,0 +1,83 @@
|
||||
{
|
||||
"id": "item-master",
|
||||
"name": "품목기준관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "품목관리 > 품목기준관리 목록/상세 기능 검증",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "품목관리",
|
||||
"level2": "품목기준관리",
|
||||
"expectedUrl": "/master-data/item-master-data-management",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 품목관리 > 품목기준관리",
|
||||
"action": "menu_navigate",
|
||||
"level1": "품목관리",
|
||||
"level2": "품목기준관리",
|
||||
"expected": { "url_contains": "/master-data" }
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "목업 감지",
|
||||
"action": "verify_not_mockup"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "품목기준관리 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:품목"]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "UI 요소 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:관리"]
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "검색 입력 시도",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[type='search'], input[placeholder*='검색'], input[placeholder*='조회'], [class*='search'] input"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "대기",
|
||||
"action": "wait",
|
||||
"duration": 1000
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "행 클릭 시도",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr, [role='row']:not(:first-child), [class*='list'] [class*='item']"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "상세 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:품목"]
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "모달 닫기",
|
||||
"action": "close_modal_if_open"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "최종 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:품목"]
|
||||
}
|
||||
]
|
||||
}
|
||||
321
_backup_before_enhance/login.json
Normal file
321
_backup_before_enhance/login.json
Normal file
@@ -0,0 +1,321 @@
|
||||
{
|
||||
"id": "login-test",
|
||||
"name": "로그인 테스트 (끝판왕)",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": [
|
||||
"error",
|
||||
"fail",
|
||||
"timeout",
|
||||
"404",
|
||||
"500",
|
||||
"blocked"
|
||||
]
|
||||
},
|
||||
"description": "로그인 페이지 UI 검증, 로그인 실패/성공, 대시보드 진입, 로그아웃까지 전체 인증 플로우 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"timeout": 30000,
|
||||
"tags": [
|
||||
"auth",
|
||||
"login",
|
||||
"critical"
|
||||
],
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!",
|
||||
"wrongPassword": "wrongpassword"
|
||||
},
|
||||
"selectors": {
|
||||
"usernameInput": "#userId",
|
||||
"passwordInput": "#password",
|
||||
"rememberMeCheckbox": "input[type='checkbox']",
|
||||
"forgotPasswordButton": "button:has-text('비밀번호를 잊으셨나요?')",
|
||||
"loginButton": "button[type='submit']",
|
||||
"passwordToggle": "button:has(.lucide-eye)",
|
||||
"userProfileButton": "button:has-text('홍킬동')",
|
||||
"logoutButton": "button:has-text('로그아웃')"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "로그인 페이지 접속",
|
||||
"action": "navigate",
|
||||
"target": "/ko/login",
|
||||
"expected": {
|
||||
"url": "/ko/login",
|
||||
"visible": [
|
||||
"로그인",
|
||||
"환영합니다",
|
||||
"SAM MES",
|
||||
"아이디",
|
||||
"비밀번호"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"아이디 입력 필드 존재 및 입력 가능",
|
||||
"비밀번호 입력 필드 존재 및 입력 가능",
|
||||
"로그인 버튼 존재 및 클릭 가능"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "UI 요소 검증 - 입력 필드",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"아이디 입력 필드 placeholder: '아이디를 입력하세요'",
|
||||
"비밀번호 입력 필드 placeholder: '비밀번호를 입력하세요'",
|
||||
"비밀번호 표시/숨김 토글 버튼 존재"
|
||||
],
|
||||
"expected": "모든 입력 필드 정상"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "UI 요소 검증 - 옵션",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"로그인 상태 유지 체크박스 존재",
|
||||
"비밀번호 찾기 링크 존재",
|
||||
"로그인 버튼 존재"
|
||||
],
|
||||
"expected": "모든 옵션 요소 정상"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "비밀번호 표시/숨김 토글 테스트",
|
||||
"action": "click_if_exists",
|
||||
"target": "passwordToggle",
|
||||
"expected": "비밀번호 필드 type이 'text'로 변경 (표시 모드)"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "비밀번호 숨김 복원",
|
||||
"action": "click_if_exists",
|
||||
"target": "passwordToggle",
|
||||
"expected": "비밀번호 필드 type이 'password'로 복원 (숨김 모드)"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "로그인 실패 테스트 - 빈 필드",
|
||||
"action": "click_if_exists",
|
||||
"target": "loginButton",
|
||||
"expected": "유효성 검사 에러 또는 로그인 실패 메시지"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "아이디 입력",
|
||||
"action": "click_if_exists",
|
||||
"target": "usernameInput",
|
||||
"value": "TestUser5",
|
||||
"expected": "아이디 필드에 값 입력됨"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "로그인 실패 테스트 - 잘못된 비밀번호",
|
||||
"action": "click_if_exists",
|
||||
"target": "passwordInput",
|
||||
"value": "wrongpassword",
|
||||
"expected": "비밀번호 필드에 값 입력됨"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "잘못된 비밀번호로 로그인 시도",
|
||||
"action": "click_if_exists",
|
||||
"target": "loginButton",
|
||||
"expected": "로그인 실패 에러 메시지 표시",
|
||||
"verify": {
|
||||
"type": "error_message",
|
||||
"contains": [
|
||||
"실패",
|
||||
"오류",
|
||||
"일치하지 않",
|
||||
"incorrect",
|
||||
"failed"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "비밀번호 필드 초기화",
|
||||
"action": "click_if_exists",
|
||||
"target": "passwordInput",
|
||||
"expected": "비밀번호 필드 비워짐"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "올바른 비밀번호 입력",
|
||||
"action": "click_if_exists",
|
||||
"target": "passwordInput",
|
||||
"value": "password123!",
|
||||
"expected": "올바른 비밀번호 입력됨"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"name": "필수 검증 #2: 로그인 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "loginButton",
|
||||
"verify": {
|
||||
"url_should_change": true,
|
||||
"no_error_page": true,
|
||||
"api_call": "POST /api/v1/auth/login"
|
||||
},
|
||||
"expected": "로그인 성공 및 대시보드로 이동"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"name": "대시보드 페이지 확인",
|
||||
"action": "wait_for_navigation",
|
||||
"expected": {
|
||||
"url_contains": "/dashboard",
|
||||
"visible": [
|
||||
"대시보드",
|
||||
"홍킬동"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"name": "사용자 정보 표시 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"사용자명 '홍킬동' 표시",
|
||||
"메뉴 영역 표시",
|
||||
"SAM 로고 표시"
|
||||
],
|
||||
"expected": "사용자 정보 및 메인 레이아웃 정상"
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"name": "세션 유지 확인 - 페이지 새로고침",
|
||||
"action": "reload",
|
||||
"expected": "새로고침 후에도 로그인 상태 유지"
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"name": "새로고침 후 대시보드 유지 확인",
|
||||
"action": "verify_url",
|
||||
"expected": {
|
||||
"url_contains": "/dashboard",
|
||||
"visible": [
|
||||
"대시보드",
|
||||
"홍킬동"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"name": "사용자 프로필 메뉴 열기",
|
||||
"action": "click_if_exists",
|
||||
"target": "userProfileButton",
|
||||
"expected": "사용자 메뉴 드롭다운 열림"
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"name": "로그아웃 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "logoutButton",
|
||||
"expected": "로그아웃 처리 및 로그인 페이지로 이동"
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"name": "로그아웃 후 로그인 페이지 확인",
|
||||
"action": "verify_element",
|
||||
"expected": {
|
||||
"url_contains": "/login",
|
||||
"visible": [
|
||||
"로그인",
|
||||
"아이디",
|
||||
"비밀번호"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"name": "로그아웃 후 보호된 페이지 접근 시도",
|
||||
"action": "navigate",
|
||||
"target": "/ko/dashboard",
|
||||
"expected": "로그인 페이지로 리다이렉트"
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"name": "재로그인 테스트",
|
||||
"actions": [
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "usernameInput",
|
||||
"value": "TestUser5"
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "passwordInput",
|
||||
"value": "password123!"
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "loginButton"
|
||||
}
|
||||
],
|
||||
"expected": "재로그인 성공"
|
||||
},
|
||||
{
|
||||
"id": 23,
|
||||
"name": "최종 확인 - 대시보드 진입",
|
||||
"action": "verify_url",
|
||||
"expected": {
|
||||
"url_contains": "/dashboard",
|
||||
"visible": [
|
||||
"대시보드",
|
||||
"홍킬동"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 2,
|
||||
"name": "등록/저장 버튼 (로그인)",
|
||||
"steps": [
|
||||
13
|
||||
],
|
||||
"criteria": "로그인 버튼 클릭 → API 호출 → 대시보드 이동"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [
|
||||
2
|
||||
],
|
||||
"criteria": "입력 필드 동작, 버튼 클릭 가능"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "POST",
|
||||
"endpoint": "/api/v1/auth/login",
|
||||
"description": "로그인 인증"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/auth/me",
|
||||
"description": "현재 사용자 정보 조회"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"endpoint": "/api/v1/auth/logout",
|
||||
"description": "로그아웃"
|
||||
}
|
||||
],
|
||||
"testData": {
|
||||
"validUser": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!",
|
||||
"displayName": "홍킬동"
|
||||
},
|
||||
"invalidPassword": "wrongpassword"
|
||||
}
|
||||
}
|
||||
301
_backup_before_enhance/material-receiving.json
Normal file
301
_backup_before_enhance/material-receiving.json
Normal file
@@ -0,0 +1,301 @@
|
||||
{
|
||||
"id": "material-receiving",
|
||||
"name": "입고관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "자재관리 > 입고관리 메뉴의 입고 조회/등록/수정/삭제 전체 CRUD 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "자재관리",
|
||||
"level2": "입고관리",
|
||||
"expectedUrl": "/material/receiving-management",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"testData": {
|
||||
"create": {
|
||||
"itemName": "E2E_TEST_입고품목",
|
||||
"quantity": "100",
|
||||
"vendor": "테스트거래처",
|
||||
"memo": "E2E 자동화 테스트 입고"
|
||||
},
|
||||
"update": {
|
||||
"quantity": "150",
|
||||
"memo": "E2E 수정된 입고 메모"
|
||||
}
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 자재관리 > 입고관리",
|
||||
"action": "menu_navigate",
|
||||
"level1": "자재관리",
|
||||
"level2": "입고관리",
|
||||
"expected": {
|
||||
"url_contains": "/material/receiving",
|
||||
"visible": ["입고관리", "입고"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"입고 목록 표시",
|
||||
"입고 등록 버튼 존재",
|
||||
"검색/필터 기능 존재"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "입고 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
"입고일 컬럼",
|
||||
"품목 컬럼",
|
||||
"수량 컬럼",
|
||||
"거래처 컬럼",
|
||||
"상태 컬럼"
|
||||
],
|
||||
"expected": "입고 테이블 컬럼 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "검색 기능 테스트",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[placeholder*='검색']",
|
||||
"value": "테스트",
|
||||
"expected": {
|
||||
"data_filtered": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 입고 등록 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('등록'), button:has-text('입고 등록'), button:has-text('추가')",
|
||||
"expected": {
|
||||
"modal": true,
|
||||
"modalTitle": "입고 등록"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 입고 정보 입력",
|
||||
"action": "fill_form",
|
||||
"fields": [
|
||||
{"name": "입고일", "type": "date", "value": "2026-02-03"},
|
||||
{"name": "품목", "type": "select", "value": "E2E_TEST_입고품목"},
|
||||
{"name": "수량", "type": "number", "value": "100"},
|
||||
{"name": "거래처", "type": "select", "value": "테스트거래처"},
|
||||
{"name": "메모", "type": "text", "value": "E2E 자동화 테스트 입고_{timestamp}"}
|
||||
],
|
||||
"note": "타임스탬프로 고유성 보장"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 필수 검증 #2: 등록 저장",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('저장'), button:has-text('등록')",
|
||||
"verify": {
|
||||
"url_maintained": true,
|
||||
"no_error_page": true,
|
||||
"api_call": "POST /api/v1/receivings",
|
||||
"toast": "등록|완료|성공"
|
||||
},
|
||||
"expected": "입고 등록 완료"
|
||||
},
|
||||
{
|
||||
"id": "7-modal-close",
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 모달 닫기 확인",
|
||||
"action": "close_modal_if_open",
|
||||
"expected": "모달 닫힘"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 등록 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"search": "E2E 자동화 테스트 입고",
|
||||
"expected": {
|
||||
"row_exists": true,
|
||||
"contains": ["E2E", "100"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 입고 상세 페이지 진입",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:has-text('E2E')",
|
||||
"expected": {
|
||||
"url_contains": "/material/receiving",
|
||||
"visible": ["입고 상세", "수정", "삭제"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"수량: 100",
|
||||
"메모: E2E 자동화 테스트"
|
||||
],
|
||||
"expected": "입력한 데이터와 일치"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 모드 진입",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('수정')",
|
||||
"expected": {
|
||||
"url_contains": "mode=edit",
|
||||
"fields_editable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수량 수정",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[name*='quantity'], input[placeholder*='수량']",
|
||||
"value": "150",
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 메모 수정",
|
||||
"action": "click_if_exists",
|
||||
"target": "textarea[name*='memo'], input[placeholder*='메모']",
|
||||
"value": "E2E 수정된 입고 메모_{timestamp}",
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 필수 검증 #2: 수정 저장",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('저장')",
|
||||
"verify": {
|
||||
"url_maintained": true,
|
||||
"no_error_page": true,
|
||||
"api_call": "PUT /api/v1/receivings/",
|
||||
"toast": "수정|완료|성공"
|
||||
},
|
||||
"expected": "수정 완료"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"수량: 150",
|
||||
"메모: E2E 수정된 입고"
|
||||
],
|
||||
"expected": "수정된 데이터 반영"
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 삭제 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('삭제')",
|
||||
"expected": {
|
||||
"confirm_dialog": true,
|
||||
"dialog_message": "삭제|정말"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 필수 검증 #6: 삭제 확인",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('확인'), button:has-text('삭제')",
|
||||
"verify": {
|
||||
"api_call": "DELETE /api/v1/receivings/",
|
||||
"toast": "삭제|완료|성공",
|
||||
"redirect": "/material/receiving"
|
||||
},
|
||||
"expected": "삭제 완료 및 목록 복귀"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 삭제 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"search": "E2E 수정된 입고",
|
||||
"expected": {
|
||||
"row_exists": false,
|
||||
"message": "테스트 입고가 목록에서 제거됨"
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/receivings",
|
||||
"description": "입고 목록 조회"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"endpoint": "/api/v1/receivings",
|
||||
"description": "입고 등록"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/receivings/{id}",
|
||||
"description": "입고 상세 조회"
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"endpoint": "/api/v1/receivings/{id}",
|
||||
"description": "입고 수정"
|
||||
},
|
||||
{
|
||||
"method": "DELETE",
|
||||
"endpoint": "/api/v1/receivings/{id}",
|
||||
"description": "입고 삭제"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 2,
|
||||
"name": "등록/저장 버튼",
|
||||
"steps": [7, 14],
|
||||
"criteria": "API 호출 + 성공 토스트 + 데이터 반영"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"criteria": "입고 목록, 등록 버튼, 필터 존재"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "삭제 기능",
|
||||
"steps": [16, 17, 18],
|
||||
"criteria": "DELETE API + 목록에서 제거"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"onCreateFail": "모달 닫기",
|
||||
"onUpdateFail": "테스트 입고 수동 삭제 필요",
|
||||
"onDeleteFail": "테스트 입고 수동 삭제 필요",
|
||||
"cleanupRequired": "E2E_TEST_ 접두사 입고는 테스트 데이터"
|
||||
}
|
||||
}
|
||||
212
_backup_before_enhance/material-stock.json
Normal file
212
_backup_before_enhance/material-stock.json
Normal file
@@ -0,0 +1,212 @@
|
||||
{
|
||||
"id": "material-stock",
|
||||
"name": "재고현황 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "자재관리 > 재고현황 메뉴의 재고 현황 조회/검색/필터/다운로드 기능 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "자재관리",
|
||||
"level2": "재고현황",
|
||||
"expectedUrl": "/material/stock-status",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 자재관리 > 재고현황",
|
||||
"action": "menu_navigate",
|
||||
"level1": "자재관리",
|
||||
"level2": "재고현황",
|
||||
"expected": {
|
||||
"url_contains": "/material/stock",
|
||||
"visible": ["재고현황", "재고"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"재고 목록 표시",
|
||||
"검색 기능 존재",
|
||||
"필터 존재"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "재고현황 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
"품목코드 컬럼",
|
||||
"품목명 컬럼",
|
||||
"현재고 컬럼",
|
||||
"안전재고 컬럼",
|
||||
"위치/창고 컬럼"
|
||||
],
|
||||
"expected": "재고 테이블 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 재고 데이터 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"재고 데이터 행 존재 또는 '데이터 없음' 메시지"
|
||||
],
|
||||
"expected": "재고 데이터 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "SEARCH",
|
||||
"name": "[SEARCH] 품목 검색",
|
||||
"action": "fill",
|
||||
"target": "input[type='search'], input[placeholder*='검색']",
|
||||
"value": "테스트",
|
||||
"submit": true
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"phase": "SEARCH",
|
||||
"name": "[SEARCH] 검색 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"검색 결과 표시 또는 결과 없음 메시지"
|
||||
],
|
||||
"expected": "검색 기능 동작"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "SEARCH",
|
||||
"name": "[SEARCH] 검색 초기화",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('초기화'), button:has-text('리셋'), button[class*='clear']",
|
||||
"expected": "검색 초기화"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 창고/위치 필터",
|
||||
"action": "click_if_exists",
|
||||
"target": "select[name*='warehouse'], select[name*='location'], button:has-text('창고')",
|
||||
"expected": "창고 필터 옵션 표시"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 재고 상태 필터",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"재고 부족/적정/과다 필터 가능"
|
||||
],
|
||||
"expected": "재고 상태 필터 표시"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "안전재고 이하 품목 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"안전재고 이하 품목 강조 표시",
|
||||
"부족 재고 경고 표시"
|
||||
],
|
||||
"expected": "안전재고 알림 표시"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "재고 이동 이력 링크",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"재고 이동 이력 조회 버튼 또는 링크"
|
||||
],
|
||||
"expected": "이력 조회 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "재고 현황 요약",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"총 품목 수",
|
||||
"재고 금액 합계",
|
||||
"부족 품목 수"
|
||||
],
|
||||
"expected": "요약 정보 표시"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"name": "필수 검증 #1: 엑셀 다운로드",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('엑셀'), button:has-text('Excel'), button:has-text('다운로드')",
|
||||
"verify": {
|
||||
"api_call": "GET /api/v1/material/stock/export",
|
||||
"file_download": true
|
||||
},
|
||||
"expected": "엑셀 파일 다운로드"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"name": "인쇄 기능 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"인쇄 버튼 존재"
|
||||
],
|
||||
"expected": "인쇄 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"name": "재고 조정 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"재고 조정 버튼 존재 여부"
|
||||
],
|
||||
"expected": "재고 조정 기능 확인"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/material/stock",
|
||||
"description": "재고현황 조회"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/material/stock/export",
|
||||
"description": "재고현황 엑셀 다운로드"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/material/warehouses",
|
||||
"description": "창고 목록 조회"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "엑셀 다운로드",
|
||||
"steps": [13],
|
||||
"criteria": "API 호출 + 파일 다운로드"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "검색/필터",
|
||||
"steps": [5, 6, 7],
|
||||
"criteria": "검색 + 필터 기능 동작"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"criteria": "재고 목록, 검색 기능, 필터 존재"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"note": "조회 전용 페이지로 데이터 변경 없음"
|
||||
}
|
||||
}
|
||||
429
_backup_before_enhance/pdf-download-test.json
Normal file
429
_backup_before_enhance/pdf-download-test.json
Normal file
@@ -0,0 +1,429 @@
|
||||
{
|
||||
"id": "pdf-download-test",
|
||||
"name": "PDF 다운로드 전체 검사",
|
||||
"description": "PDF 다운로드 버튼이 있는 모든 페이지를 순회하며 PDF 다운로드 기능과 품질을 검증하는 E2E 테스트",
|
||||
"version": "1.0.0",
|
||||
"createdAt": "2026-01-29",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": false,
|
||||
"captureOn": ["before-download", "after-download", "error", "fail"]
|
||||
},
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"timeout": 180000,
|
||||
"tags": ["pdf", "download", "quality", "export"],
|
||||
|
||||
"login": {
|
||||
"url": "https://dev.codebridge-x.com/login",
|
||||
"credentials": {
|
||||
"id": "TestUser5",
|
||||
"password": "password123!"
|
||||
}
|
||||
},
|
||||
|
||||
"pdfTargets": [
|
||||
{
|
||||
"id": "draft-box",
|
||||
"name": "기안함 PDF",
|
||||
"menuNavigation": {
|
||||
"level1": "결재관리",
|
||||
"level2": "기안함"
|
||||
},
|
||||
"accessMethod": "modal",
|
||||
"triggerAction": "clickFirstRow",
|
||||
"pdfButtonSelector": "button:has-text('PDF')",
|
||||
"pdfApiPattern": "/api/v1/approvals/*/pdf",
|
||||
"expectedContentType": "application/pdf"
|
||||
},
|
||||
{
|
||||
"id": "approval-box",
|
||||
"name": "결재함 PDF",
|
||||
"menuNavigation": {
|
||||
"level1": "결재관리",
|
||||
"level2": "결재함"
|
||||
},
|
||||
"accessMethod": "modal",
|
||||
"triggerAction": "clickFirstRow",
|
||||
"pdfButtonSelector": "button:has-text('PDF')",
|
||||
"pdfApiPattern": "/api/v1/approvals/*/pdf",
|
||||
"expectedContentType": "application/pdf"
|
||||
},
|
||||
{
|
||||
"id": "reference-box",
|
||||
"name": "참조함 PDF",
|
||||
"menuNavigation": {
|
||||
"level1": "결재관리",
|
||||
"level2": "참조함"
|
||||
},
|
||||
"accessMethod": "modal",
|
||||
"triggerAction": "clickFirstRow",
|
||||
"pdfButtonSelector": "button:has-text('PDF')",
|
||||
"pdfApiPattern": "/api/v1/approvals/*/pdf",
|
||||
"expectedContentType": "application/pdf"
|
||||
},
|
||||
{
|
||||
"id": "vendor-ledger",
|
||||
"name": "거래처원장 PDF",
|
||||
"menuNavigation": {
|
||||
"level1": "자재관리",
|
||||
"level2": "거래처원장"
|
||||
},
|
||||
"accessMethod": "detailPage",
|
||||
"triggerAction": "clickFirstRow",
|
||||
"pdfButtonSelector": "button:has-text('PDF 다운로드')",
|
||||
"pdfApiPattern": "/api/v1/vendor-ledger/*/export-pdf",
|
||||
"expectedContentType": "application/pdf"
|
||||
}
|
||||
],
|
||||
|
||||
"steps": [
|
||||
{
|
||||
"id": "step-0",
|
||||
"name": "PDF 샘플 폴더 준비",
|
||||
"description": "PDF 파일 저장 폴더 확인",
|
||||
"setup": {
|
||||
"createFolders": [
|
||||
"react/tests/e2e/results/hotfix/pdf-samples/",
|
||||
"react/tests/e2e/results/hotfix/screenshots/"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"id": "pdf-test-1",
|
||||
"name": "기안함 PDF 다운로드 테스트",
|
||||
"target": "draft-box",
|
||||
"steps": [
|
||||
{
|
||||
"id": "1-1",
|
||||
"action": "navigate",
|
||||
"menu": { "level1": "결재관리", "level2": "기안함" },
|
||||
"expect": { "url": "/approval/drafts" }
|
||||
},
|
||||
{
|
||||
"id": "1-2",
|
||||
"action": "waitForTable",
|
||||
"timeout": 5000,
|
||||
"expect": { "rowCount": ">= 1" }
|
||||
},
|
||||
{
|
||||
"id": "1-3",
|
||||
"action": "clickFirstRow",
|
||||
"description": "첫 번째 문서 클릭하여 상세 모달 열기"
|
||||
},
|
||||
{
|
||||
"id": "1-4",
|
||||
"action": "waitForModal",
|
||||
"timeout": 3000,
|
||||
"expect": { "modalVisible": true }
|
||||
},
|
||||
{
|
||||
"id": "1-5",
|
||||
"action": "screenshot",
|
||||
"name": "draft-box_pdf-preview_{timestamp}",
|
||||
"selector": "[role='dialog'], .modal",
|
||||
"savePath": "react/tests/e2e/results/hotfix/screenshots/",
|
||||
"description": "PDF 생성 전 모달 스크린샷"
|
||||
},
|
||||
{
|
||||
"id": "1-6",
|
||||
"action": "verifyButtonExists",
|
||||
"selector": "button:has-text('PDF')",
|
||||
"expect": { "visible": true }
|
||||
},
|
||||
{
|
||||
"id": "1-7",
|
||||
"action": "setupDownloadListener",
|
||||
"description": "다운로드 이벤트 리스너 설정"
|
||||
},
|
||||
{
|
||||
"id": "1-8",
|
||||
"action": "click_if_exists",
|
||||
"selector": "button:has-text('PDF')",
|
||||
"description": "PDF 버튼 클릭"
|
||||
},
|
||||
{
|
||||
"id": "1-9",
|
||||
"action": "wait",
|
||||
"duration": 3000,
|
||||
"description": "PDF 생성 및 다운로드 대기"
|
||||
},
|
||||
{
|
||||
"id": "1-10",
|
||||
"action": "verifyDownload",
|
||||
"checks": {
|
||||
"fileDownloaded": true,
|
||||
"fileExtension": ".pdf",
|
||||
"minFileSize": 1024,
|
||||
"pdfSignature": "%PDF-"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "1-11",
|
||||
"action": "saveDownloadedFile",
|
||||
"targetPath": "react/tests/e2e/results/hotfix/pdf-samples/",
|
||||
"fileName": "draft-box_{timestamp}.pdf"
|
||||
},
|
||||
{
|
||||
"id": "1-12",
|
||||
"action": "closeModal",
|
||||
"method": "pressEscape"
|
||||
}
|
||||
],
|
||||
"onSuccess": {
|
||||
"log": "draft-box PDF 다운로드 성공",
|
||||
"recordFile": true
|
||||
},
|
||||
"onFail": {
|
||||
"screenshot": true,
|
||||
"continueToNext": true
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"id": "pdf-test-2",
|
||||
"name": "결재함 PDF 다운로드 테스트",
|
||||
"target": "approval-box",
|
||||
"steps": [
|
||||
{
|
||||
"id": "2-1",
|
||||
"action": "navigate",
|
||||
"menu": { "level1": "결재관리", "level2": "결재함" },
|
||||
"expect": { "url": "/approval/approval-box" }
|
||||
},
|
||||
{
|
||||
"id": "2-2",
|
||||
"action": "waitForTable",
|
||||
"timeout": 5000,
|
||||
"expect": { "rowCount": ">= 1" }
|
||||
},
|
||||
{
|
||||
"id": "2-3",
|
||||
"action": "clickFirstRow",
|
||||
"description": "첫 번째 문서 클릭하여 상세 모달 열기"
|
||||
},
|
||||
{
|
||||
"id": "2-4",
|
||||
"action": "waitForModal",
|
||||
"timeout": 3000
|
||||
},
|
||||
{
|
||||
"id": "2-5",
|
||||
"action": "screenshot",
|
||||
"name": "approval-box_pdf-preview_{timestamp}",
|
||||
"selector": "[role='dialog'], .modal",
|
||||
"savePath": "react/tests/e2e/results/hotfix/screenshots/"
|
||||
},
|
||||
{
|
||||
"id": "2-6",
|
||||
"action": "click_if_exists",
|
||||
"selector": "button:has-text('PDF')"
|
||||
},
|
||||
{
|
||||
"id": "2-7",
|
||||
"action": "wait",
|
||||
"duration": 3000
|
||||
},
|
||||
{
|
||||
"id": "2-8",
|
||||
"action": "verifyDownload",
|
||||
"checks": {
|
||||
"fileDownloaded": true,
|
||||
"fileExtension": ".pdf",
|
||||
"minFileSize": 1024
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "2-9",
|
||||
"action": "saveDownloadedFile",
|
||||
"targetPath": "react/tests/e2e/results/hotfix/pdf-samples/",
|
||||
"fileName": "approval-box_{timestamp}.pdf"
|
||||
},
|
||||
{
|
||||
"id": "2-10",
|
||||
"action": "closeModal"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"id": "pdf-test-3",
|
||||
"name": "참조함 PDF 다운로드 테스트",
|
||||
"target": "reference-box",
|
||||
"steps": [
|
||||
{
|
||||
"id": "3-1",
|
||||
"action": "navigate",
|
||||
"menu": { "level1": "결재관리", "level2": "참조함" },
|
||||
"expect": { "url": "/approval/reference-box" }
|
||||
},
|
||||
{
|
||||
"id": "3-2",
|
||||
"action": "waitForTable",
|
||||
"timeout": 5000,
|
||||
"expect": { "rowCount": ">= 1" }
|
||||
},
|
||||
{
|
||||
"id": "3-3",
|
||||
"action": "clickFirstRow"
|
||||
},
|
||||
{
|
||||
"id": "3-4",
|
||||
"action": "waitForModal",
|
||||
"timeout": 3000
|
||||
},
|
||||
{
|
||||
"id": "3-5",
|
||||
"action": "screenshot",
|
||||
"name": "reference-box_pdf-preview_{timestamp}",
|
||||
"selector": "[role='dialog'], .modal",
|
||||
"savePath": "react/tests/e2e/results/hotfix/screenshots/"
|
||||
},
|
||||
{
|
||||
"id": "3-6",
|
||||
"action": "click_if_exists",
|
||||
"selector": "button:has-text('PDF')"
|
||||
},
|
||||
{
|
||||
"id": "3-7",
|
||||
"action": "wait",
|
||||
"duration": 3000
|
||||
},
|
||||
{
|
||||
"id": "3-8",
|
||||
"action": "verifyDownload",
|
||||
"checks": {
|
||||
"fileDownloaded": true,
|
||||
"fileExtension": ".pdf",
|
||||
"minFileSize": 1024
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "3-9",
|
||||
"action": "saveDownloadedFile",
|
||||
"targetPath": "react/tests/e2e/results/hotfix/pdf-samples/",
|
||||
"fileName": "reference-box_{timestamp}.pdf"
|
||||
},
|
||||
{
|
||||
"id": "3-10",
|
||||
"action": "closeModal"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"id": "pdf-test-4",
|
||||
"name": "거래처원장 PDF 다운로드 테스트",
|
||||
"target": "vendor-ledger",
|
||||
"steps": [
|
||||
{
|
||||
"id": "4-1",
|
||||
"action": "navigate",
|
||||
"menu": { "level1": "자재관리", "level2": "거래처원장" },
|
||||
"expect": { "url": "/accounting/vendor-ledger" }
|
||||
},
|
||||
{
|
||||
"id": "4-2",
|
||||
"action": "waitForTable",
|
||||
"timeout": 5000,
|
||||
"expect": { "rowCount": ">= 1" }
|
||||
},
|
||||
{
|
||||
"id": "4-3",
|
||||
"action": "clickFirstRow",
|
||||
"description": "거래처 클릭하여 상세 페이지 이동"
|
||||
},
|
||||
{
|
||||
"id": "4-4",
|
||||
"action": "waitForNavigation",
|
||||
"timeout": 5000,
|
||||
"expect": { "urlContains": "/accounting/vendor-ledger/" }
|
||||
},
|
||||
{
|
||||
"id": "4-5",
|
||||
"action": "screenshot",
|
||||
"name": "vendor-ledger_pdf-preview_{timestamp}",
|
||||
"fullPage": true,
|
||||
"savePath": "react/tests/e2e/results/hotfix/screenshots/"
|
||||
},
|
||||
{
|
||||
"id": "4-6",
|
||||
"action": "verifyButtonExists",
|
||||
"selector": "button:has-text('PDF 다운로드')",
|
||||
"expect": { "visible": true, "count": ">= 1" }
|
||||
},
|
||||
{
|
||||
"id": "4-7",
|
||||
"action": "click_if_exists",
|
||||
"selector": "button:has-text('PDF 다운로드')",
|
||||
"index": 0,
|
||||
"description": "첫 번째 PDF 다운로드 버튼 클릭"
|
||||
},
|
||||
{
|
||||
"id": "4-8",
|
||||
"action": "wait",
|
||||
"duration": 3000
|
||||
},
|
||||
{
|
||||
"id": "4-9",
|
||||
"action": "verifyDownload",
|
||||
"checks": {
|
||||
"fileDownloaded": true,
|
||||
"fileExtension": ".pdf",
|
||||
"minFileSize": 1024
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "4-10",
|
||||
"action": "saveDownloadedFile",
|
||||
"targetPath": "react/tests/e2e/results/hotfix/pdf-samples/",
|
||||
"fileName": "vendor-ledger_{timestamp}.pdf"
|
||||
},
|
||||
{
|
||||
"id": "4-11",
|
||||
"action": "navigateBack",
|
||||
"description": "목록으로 돌아가기"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
"pdfQualityChecklist": {
|
||||
"description": "다운로드된 PDF 파일 수동 검증 체크리스트",
|
||||
"items": [
|
||||
{ "id": "q1", "category": "파일", "item": "PDF 파일이 정상적으로 열리는가?" },
|
||||
{ "id": "q2", "category": "폰트", "item": "한글 폰트가 깨지지 않고 정상 표시되는가?" },
|
||||
{ "id": "q3", "category": "테이블", "item": "테이블 경계선이 올바르게 표시되는가?" },
|
||||
{ "id": "q4", "category": "정렬", "item": "숫자/금액이 우측 정렬되어 있는가?" },
|
||||
{ "id": "q5", "category": "레이아웃", "item": "여백(margin/padding)이 적절한가?" },
|
||||
{ "id": "q6", "category": "페이지", "item": "헤더/푸터가 각 페이지에 올바르게 표시되는가?" },
|
||||
{ "id": "q7", "category": "이미지", "item": "로고/이미지가 정상 표시되는가?" },
|
||||
{ "id": "q8", "category": "페이지나눔", "item": "페이지 나눔이 적절한 위치에서 발생하는가?" },
|
||||
{ "id": "q9", "category": "색상", "item": "배경색/강조색이 올바르게 적용되었는가?" },
|
||||
{ "id": "q10", "category": "오버플로우", "item": "텍스트가 잘리거나 겹치지 않는가?" }
|
||||
]
|
||||
},
|
||||
|
||||
"outputPaths": {
|
||||
"pdfSamples": "react/tests/e2e/results/hotfix/pdf-samples/",
|
||||
"screenshots": "react/tests/e2e/results/hotfix/screenshots/",
|
||||
"report": "react/tests/e2e/results/hotfix/"
|
||||
},
|
||||
|
||||
"reportTemplate": {
|
||||
"successFile": "OK-pdf-download-test_{timestamp}.md",
|
||||
"failFile": "Fail-pdf-download-test_{timestamp}.md",
|
||||
"sections": [
|
||||
"테스트 요약",
|
||||
"개별 PDF 테스트 결과",
|
||||
"다운로드된 PDF 파일 목록",
|
||||
"품질 체크리스트 (수동 확인 필요)"
|
||||
]
|
||||
},
|
||||
|
||||
"executionNotes": [
|
||||
"이 시나리오는 'PDF 다운로드 전체 검사해줘' 명령으로 실행",
|
||||
"각 PDF 버튼 클릭 후 3초 대기 (PDF 생성 시간)",
|
||||
"다운로드된 PDF는 pdf-samples 폴더에 타임스탬프와 함께 저장",
|
||||
"테스트 완료 후 PDF 파일을 열어 품질 체크리스트 수동 확인 필요"
|
||||
]
|
||||
}
|
||||
71
_backup_before_enhance/production-dashboard.json
Normal file
71
_backup_before_enhance/production-dashboard.json
Normal file
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"id": "production-dashboard",
|
||||
"name": "생산 현황판 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "생산관리 > 생산 현황판 대시보드 기능 검증",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "생산관리",
|
||||
"level2": "생산 현황판",
|
||||
"expectedUrl": "/production/dashboard",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 생산관리 > 생산 현황판",
|
||||
"action": "menu_navigate",
|
||||
"level1": "생산관리",
|
||||
"level2": "생산 현황판",
|
||||
"expected": { "url_contains": "/production" }
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "목업 감지",
|
||||
"action": "verify_not_mockup"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "생산 현황판 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:생산"]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "현황 데이터 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:현황"]
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "필터 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('필터'), select, [class*='filter'] button, [class*='date-picker']"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "대기",
|
||||
"action": "wait",
|
||||
"duration": 1000
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "모달 닫기",
|
||||
"action": "close_modal_if_open"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "생산 현황판 최종 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:생산"]
|
||||
}
|
||||
]
|
||||
}
|
||||
83
_backup_before_enhance/production-item.json
Normal file
83
_backup_before_enhance/production-item.json
Normal file
@@ -0,0 +1,83 @@
|
||||
{
|
||||
"id": "production-item",
|
||||
"name": "생산품목관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "품목관리 > 품목기준관리 목록/검색/상세 기능 검증",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "품목관리",
|
||||
"level2": "품목기준관리",
|
||||
"expectedUrl": "/master-data/item-master-data-management",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 품목관리 > 품목기준관리",
|
||||
"action": "menu_navigate",
|
||||
"level1": "품목관리",
|
||||
"level2": "품목기준관리",
|
||||
"expected": { "url_contains": "/master-data" }
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "목업 감지",
|
||||
"action": "verify_not_mockup"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "품목기준관리 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:품목"]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "테이블 또는 목록 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:관리"]
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "검색 입력 시도",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[type='search'], input[placeholder*='검색'], input[placeholder*='조회'], [class*='search'] input"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "대기",
|
||||
"action": "wait",
|
||||
"duration": 1000
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "행 클릭 시도",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr, [role='row']:not(:first-child), [class*='list'] [class*='item']"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "상세 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:품목"]
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "모달 닫기",
|
||||
"action": "close_modal_if_open"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "최종 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:품목"]
|
||||
}
|
||||
]
|
||||
}
|
||||
350
_backup_before_enhance/production-work-order.json
Normal file
350
_backup_before_enhance/production-work-order.json
Normal file
@@ -0,0 +1,350 @@
|
||||
{
|
||||
"enabled": true,
|
||||
"id": "production-work-order",
|
||||
"name": "작업지시 관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": [
|
||||
"error",
|
||||
"fail",
|
||||
"timeout",
|
||||
"404",
|
||||
"500",
|
||||
"blocked"
|
||||
]
|
||||
},
|
||||
"description": "생산관리 > 작업지시 관리 메뉴의 작업지시 조회/등록/수정/삭제 전체 CRUD 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "생산관리",
|
||||
"level2": "작업지시 관리",
|
||||
"expectedUrl": "/production/work-orders",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"testData": {
|
||||
"create": {
|
||||
"orderNumber": "E2E_TEST_작업지시",
|
||||
"itemName": "테스트품목",
|
||||
"quantity": "500",
|
||||
"dueDate": "2026-02-10",
|
||||
"memo": "E2E 자동화 테스트 작업지시"
|
||||
},
|
||||
"update": {
|
||||
"quantity": "600",
|
||||
"memo": "E2E 수정된 작업지시 메모"
|
||||
}
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 생산관리 > 작업지시 관리",
|
||||
"action": "menu_navigate",
|
||||
"level1": "생산관리",
|
||||
"level2": "작업지시 관리",
|
||||
"expected": {
|
||||
"url_contains": "/production/work-orders",
|
||||
"visible": [
|
||||
"작업지시"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"작업지시 목록 표시",
|
||||
"작업지시 등록 버튼 존재",
|
||||
"검색/필터 기능 존재"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "작업지시 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
"작업지시번호 컬럼",
|
||||
"품목 컬럼",
|
||||
"수량 컬럼",
|
||||
"납기일 컬럼",
|
||||
"상태 컬럼"
|
||||
],
|
||||
"expected": "작업지시 테이블 컬럼 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "검색 기능 테스트",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[placeholder*='검색']",
|
||||
"value": "테스트",
|
||||
"expected": {
|
||||
"data_filtered": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 작업지시 등록 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('등록'), button:has-text('작업지시 등록'), button:has-text('추가')",
|
||||
"expected": {
|
||||
"modal": true,
|
||||
"modalTitle": "작업지시 등록"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 작업지시 정보 입력",
|
||||
"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 자동화 테스트 작업지시"
|
||||
}
|
||||
],
|
||||
"note": "타임스탬프로 고유성 보장",
|
||||
"target": "form, [role='dialog'], .modal"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 필수 검증 #2: 등록 저장",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('저장'), button:has-text('등록')",
|
||||
"verify": {
|
||||
"url_maintained": true,
|
||||
"no_error_page": true,
|
||||
"api_call": "POST /api/v1/work-orders",
|
||||
"toast": "등록|완료|성공"
|
||||
},
|
||||
"expected": "작업지시 등록 완료"
|
||||
},
|
||||
{
|
||||
"id": "7-modal-close",
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 모달 닫기 확인",
|
||||
"action": "close_modal_if_open",
|
||||
"expected": "모달 닫힘"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 등록 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"search": "E2E_TEST_작업지시",
|
||||
"expected": {
|
||||
"row_exists": true,
|
||||
"contains": [
|
||||
"E2E",
|
||||
"500"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 작업지시 상세 페이지 진입",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:has-text('E2E')",
|
||||
"expected": {
|
||||
"url_contains": "/production/work-orders/",
|
||||
"visible": [
|
||||
"작업지시 상세",
|
||||
"수정",
|
||||
"삭제"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"작업지시번호: E2E_TEST_작업지시",
|
||||
"수량: 500",
|
||||
"납기일: 2026-02-10"
|
||||
],
|
||||
"expected": "입력한 데이터와 일치"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 모드 진입",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('수정')",
|
||||
"expected": {
|
||||
"url_contains": "mode=edit",
|
||||
"fields_editable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수량 수정",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[name*='quantity'], input[placeholder*='수량']",
|
||||
"value": "600",
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 메모 수정",
|
||||
"action": "click_if_exists",
|
||||
"target": "textarea[name*='memo'], input[placeholder*='메모']",
|
||||
"value": "E2E 수정된 작업지시 메모_{timestamp}",
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 필수 검증 #2: 수정 저장",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('저장')",
|
||||
"verify": {
|
||||
"url_maintained": true,
|
||||
"no_error_page": true,
|
||||
"api_call": "PUT /api/v1/work-orders/",
|
||||
"toast": "수정|완료|성공"
|
||||
},
|
||||
"expected": "수정 완료"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"수량: 600",
|
||||
"메모: E2E 수정된 작업지시"
|
||||
],
|
||||
"expected": "수정된 데이터 반영"
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 삭제 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('삭제')",
|
||||
"expected": {
|
||||
"confirm_dialog": true,
|
||||
"dialog_message": "삭제|정말"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 필수 검증 #6: 삭제 확인",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('확인'), button:has-text('삭제')",
|
||||
"verify": {
|
||||
"api_call": "DELETE /api/v1/work-orders/",
|
||||
"toast": "삭제|완료|성공",
|
||||
"redirect": "/production/work-orders"
|
||||
},
|
||||
"expected": "삭제 완료 및 목록 복귀"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 삭제 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"search": "E2E 수정된 작업지시",
|
||||
"expected": {
|
||||
"row_exists": false,
|
||||
"message": "테스트 작업지시가 목록에서 제거됨"
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/work-orders",
|
||||
"description": "작업지시 목록 조회"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"endpoint": "/api/v1/work-orders",
|
||||
"description": "작업지시 등록"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/work-orders/{id}",
|
||||
"description": "작업지시 상세 조회"
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"endpoint": "/api/v1/work-orders/{id}",
|
||||
"description": "작업지시 수정"
|
||||
},
|
||||
{
|
||||
"method": "DELETE",
|
||||
"endpoint": "/api/v1/work-orders/{id}",
|
||||
"description": "작업지시 삭제"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 2,
|
||||
"name": "등록/저장 버튼",
|
||||
"steps": [
|
||||
7,
|
||||
14
|
||||
],
|
||||
"criteria": "API 호출 + 성공 토스트 + 데이터 반영"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [
|
||||
2
|
||||
],
|
||||
"criteria": "작업지시 목록, 등록 버튼, 필터 존재"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "삭제 기능",
|
||||
"steps": [
|
||||
16,
|
||||
17,
|
||||
18
|
||||
],
|
||||
"criteria": "DELETE API + 목록에서 제거"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"onCreateFail": "모달 닫기",
|
||||
"onUpdateFail": "테스트 작업지시 수동 삭제 필요",
|
||||
"onDeleteFail": "테스트 작업지시 수동 삭제 필요",
|
||||
"cleanupRequired": "E2E_TEST_ 접두사 작업지시는 테스트 데이터"
|
||||
}
|
||||
}
|
||||
257
_backup_before_enhance/production-work-result.json
Normal file
257
_backup_before_enhance/production-work-result.json
Normal file
@@ -0,0 +1,257 @@
|
||||
{
|
||||
"enabled": true,
|
||||
"id": "production-work-result",
|
||||
"name": "작업실적 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "생산관리 > 작업실적 메뉴의 작업 실적 CRUD 기능 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "생산관리",
|
||||
"level2": "작업실적",
|
||||
"expectedUrl": "/production/work-results",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"testData": {
|
||||
"create": {
|
||||
"description": "E2E_TEST_실적_{timestamp}",
|
||||
"quantity": "100",
|
||||
"defectQty": "5"
|
||||
}
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 생산관리 > 작업실적",
|
||||
"action": "menu_navigate",
|
||||
"level1": "생산관리",
|
||||
"level2": "작업실적",
|
||||
"expected": {
|
||||
"url_contains": "/production/work",
|
||||
"visible": ["작업실적"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"작업실적 목록 표시",
|
||||
"실적 등록 버튼 존재",
|
||||
"기간 필터 존재"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "작업실적 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
"작업일 컬럼",
|
||||
"품목 컬럼",
|
||||
"지시 수량 컬럼",
|
||||
"실적 수량 컬럼",
|
||||
"작업자 컬럼"
|
||||
],
|
||||
"expected": "작업실적 테이블 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 기간 필터 - 시작일",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[type='date']:first-of-type, input[name*='start']",
|
||||
"value": "2025-01-01"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 기간 필터 - 종료일",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[type='date']:last-of-type, input[name*='end']",
|
||||
"value": "2025-12-31"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 조회 실행",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('조회'), button:has-text('검색')",
|
||||
"expected": {
|
||||
"api_call": "GET /api/v1/production/work-results"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 실적 등록 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('등록'), button:has-text('추가'), button:has-text('신규')",
|
||||
"expected": {
|
||||
"modal_open": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 작업 지시 선택",
|
||||
"action": "click_if_exists",
|
||||
"target": "select[name*='order'], button:has-text('작업지시'), input[placeholder*='작업지시']",
|
||||
"expected": "작업 지시 선택 가능"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 생산 수량 입력",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[name*='quantity'], input[name*='qty'], input[placeholder*='수량']",
|
||||
"value": "100",
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 불량 수량 입력",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[name*='defect'], input[placeholder*='불량']",
|
||||
"value": "5",
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 필수 검증 #2: 실적 저장",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('저장'), button:has-text('등록'), button:has-text('확인')",
|
||||
"verify": {
|
||||
"url_maintained": true,
|
||||
"no_error_page": true,
|
||||
"api_call": "POST /api/v1/production/work-results",
|
||||
"toast": "등록|저장|완료|성공"
|
||||
},
|
||||
"expected": "실적 등록 완료"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 등록된 실적 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"등록한 실적 목록에 표시"
|
||||
],
|
||||
"expected": "등록된 실적 확인"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 실적 상세 조회",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:first-child",
|
||||
"expected": {
|
||||
"detail_view": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"name": "실적 상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"작업일시",
|
||||
"품목 정보",
|
||||
"생산 수량",
|
||||
"불량 수량",
|
||||
"작업자 정보"
|
||||
],
|
||||
"expected": "실적 상세 정보 표시"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 실적 수정",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('수정'), button:has-text('편집')",
|
||||
"expected": {
|
||||
"edit_mode": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수량 수정",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[name*='quantity'], input[name*='qty']",
|
||||
"value": "95",
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 저장",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('저장'), button:has-text('확인')",
|
||||
"verify": {
|
||||
"api_call": "PUT /api/v1/production/work-results",
|
||||
"toast": "수정|저장|완료|성공"
|
||||
},
|
||||
"expected": "실적 수정 완료"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"name": "엑셀 다운로드 확인",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('엑셀'), button:has-text('Excel'), button:has-text('다운로드')",
|
||||
"verify": {
|
||||
"file_download": true
|
||||
},
|
||||
"expected": "엑셀 파일 다운로드"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/production/work-results",
|
||||
"description": "작업실적 목록 조회"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"endpoint": "/api/v1/production/work-results",
|
||||
"description": "작업실적 등록"
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"endpoint": "/api/v1/production/work-results/:id",
|
||||
"description": "작업실적 수정"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/production/work-results/export",
|
||||
"description": "작업실적 엑셀 다운로드"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 2,
|
||||
"name": "저장 버튼",
|
||||
"steps": [11, 17],
|
||||
"criteria": "API 호출 + 성공 토스트 + 데이터 반영"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"criteria": "작업실적 목록, 등록 버튼, 기간 필터 존재"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"onCreateFail": "등록 모달 닫고 재시도",
|
||||
"onUpdateFail": "페이지 새로고침 후 재시도",
|
||||
"note": "작업실적은 작업지시와 연관되어 있어 주의 필요"
|
||||
}
|
||||
}
|
||||
83
_backup_before_enhance/production-worker.json
Normal file
83
_backup_before_enhance/production-worker.json
Normal file
@@ -0,0 +1,83 @@
|
||||
{
|
||||
"id": "production-worker",
|
||||
"name": "작업자 화면 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "생산관리 > 작업자 화면 목록/상세 기능 검증",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "생산관리",
|
||||
"level2": "작업자 화면",
|
||||
"expectedUrl": "/production/worker-screen",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 생산관리 > 작업자 화면",
|
||||
"action": "menu_navigate",
|
||||
"level1": "생산관리",
|
||||
"level2": "작업자 화면",
|
||||
"expected": { "url_contains": "/production" }
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "목업 감지",
|
||||
"action": "verify_not_mockup"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "작업자 화면 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:작업"]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "UI 요소 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:관리"]
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "검색 입력 시도",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[type='search'], input[placeholder*='검색'], input[placeholder*='조회'], [class*='search'] input"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "대기",
|
||||
"action": "wait",
|
||||
"duration": 1000
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "행 클릭 시도",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr, [role='row']:not(:first-child), [class*='list'] [class*='item']"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "상세 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:작업"]
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "모달 닫기",
|
||||
"action": "close_modal_if_open"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "최종 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:작업"]
|
||||
}
|
||||
]
|
||||
}
|
||||
83
_backup_before_enhance/quality-certification.json
Normal file
83
_backup_before_enhance/quality-certification.json
Normal file
@@ -0,0 +1,83 @@
|
||||
{
|
||||
"id": "quality-certification",
|
||||
"name": "품질인정심사 시스템 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "품질관리 > 품질인정심사 시스템 목록/상세 기능 검증",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "품질관리",
|
||||
"level2": "품질인정심사 시스템",
|
||||
"expectedUrl": "/quality/qms",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 품질관리 > 품질인정심사 시스템",
|
||||
"action": "menu_navigate",
|
||||
"level1": "품질관리",
|
||||
"level2": "품질인정심사 시스템",
|
||||
"expected": { "url_contains": "/quality" }
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "목업 감지",
|
||||
"action": "verify_not_mockup"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "품질인정심사 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:품질"]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "UI 요소 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:인정"]
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "검색 입력 시도",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[type='search'], input[placeholder*='검색'], input[placeholder*='조회'], [class*='search'] input"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "대기",
|
||||
"action": "wait",
|
||||
"duration": 1000
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "행 클릭 시도",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr, [role='row']:not(:first-child), [class*='list'] [class*='item']"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "상세 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:품질"]
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "모달 닫기",
|
||||
"action": "close_modal_if_open"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "최종 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:품질"]
|
||||
}
|
||||
]
|
||||
}
|
||||
359
_backup_before_enhance/quality-inspection.json
Normal file
359
_backup_before_enhance/quality-inspection.json
Normal file
@@ -0,0 +1,359 @@
|
||||
{
|
||||
"enabled": true,
|
||||
"id": "quality-inspection",
|
||||
"name": "제품검사관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": [
|
||||
"error",
|
||||
"fail",
|
||||
"timeout",
|
||||
"404",
|
||||
"500",
|
||||
"blocked"
|
||||
]
|
||||
},
|
||||
"description": "품질관리 > 제품검사관리 메뉴의 제품검사 조회/등록/수정/삭제 전체 CRUD 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "품질관리",
|
||||
"level2": "제품검사관리",
|
||||
"expectedUrl": "/quality/inspections",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"testData": {
|
||||
"create": {
|
||||
"siteName": "E2E_TEST_현장",
|
||||
"orderCompany": "E2E_TEST_수주처",
|
||||
"location": "테스트구역A",
|
||||
"inspector": "홍길동",
|
||||
"memo": "E2E 자동화 테스트 제품검사"
|
||||
},
|
||||
"update": {
|
||||
"location": "테스트구역B",
|
||||
"memo": "E2E 수정된 제품검사 메모"
|
||||
}
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 품질관리 > 제품검사관리",
|
||||
"action": "menu_navigate",
|
||||
"level1": "품질관리",
|
||||
"level2": "제품검사관리",
|
||||
"expected": {
|
||||
"url_contains": "/quality/inspections",
|
||||
"visible": [
|
||||
"제품검사",
|
||||
"검사"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"제품검사 목록 표시",
|
||||
"제품검사 등록 버튼 존재",
|
||||
"검색/필터 기능 존재"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "제품검사 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
"품질관리서 번호 컬럼",
|
||||
"현장명 컬럼",
|
||||
"수주처 컬럼",
|
||||
"검사기간 컬럼",
|
||||
"상태 컬럼",
|
||||
"검사자 컬럼"
|
||||
],
|
||||
"expected": "제품검사 테이블 컬럼 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "검색 기능 테스트",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[placeholder*='검색']",
|
||||
"value": "테스트",
|
||||
"expected": {
|
||||
"data_filtered": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 제품검사 등록 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('등록'), button:has-text('제품검사 등록'), button:has-text('추가')",
|
||||
"expected": {
|
||||
"modal_or_page": true,
|
||||
"title": "제품검사 등록"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 제품검사 정보 입력",
|
||||
"action": "fill_form",
|
||||
"fields": [
|
||||
{
|
||||
"name": "현장명",
|
||||
"type": "text",
|
||||
"value": "E2E_TEST_현장_{timestamp}"
|
||||
},
|
||||
{
|
||||
"name": "수주처",
|
||||
"type": "select",
|
||||
"value": "E2E_TEST_수주처"
|
||||
},
|
||||
{
|
||||
"name": "개소",
|
||||
"type": "text",
|
||||
"value": "테스트구역A"
|
||||
},
|
||||
{
|
||||
"name": "검사자",
|
||||
"type": "select",
|
||||
"value": "홍길동"
|
||||
},
|
||||
{
|
||||
"name": "메모",
|
||||
"type": "text",
|
||||
"value": "E2E 자동화 테스트 제품검사_{timestamp}"
|
||||
}
|
||||
],
|
||||
"note": "타임스탬프로 고유성 보장"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 필수 검증 #2: 등록 저장",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('저장'), button:has-text('등록')",
|
||||
"verify": {
|
||||
"url_maintained": true,
|
||||
"no_error_page": true,
|
||||
"api_call": "POST /api/v1/quality/inspections",
|
||||
"toast": "등록|완료|성공"
|
||||
},
|
||||
"expected": "제품검사 등록 완료"
|
||||
},
|
||||
{
|
||||
"id": "7-modal-close",
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 모달 닫기 확인",
|
||||
"action": "close_modal_if_open",
|
||||
"expected": "모달 닫힘"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 등록 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"search": "E2E_TEST_현장",
|
||||
"expected": {
|
||||
"row_exists": true,
|
||||
"contains": [
|
||||
"E2E_TEST",
|
||||
"접수"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 제품검사 상세 페이지 진입",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:has-text('E2E_TEST')",
|
||||
"expected": {
|
||||
"url_contains": "/quality/inspections/",
|
||||
"visible": [
|
||||
"품질관리서",
|
||||
"수정",
|
||||
"삭제"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"현장명: E2E_TEST_현장",
|
||||
"개소: 테스트구역A",
|
||||
"검사자: 홍길동"
|
||||
],
|
||||
"expected": "입력한 데이터와 일치"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 모드 진입",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('수정')",
|
||||
"expected": {
|
||||
"url_contains": "mode=edit",
|
||||
"fields_editable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 개소 수정",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[name*='location'], input[placeholder*='개소']",
|
||||
"value": "테스트구역B",
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 메모 수정",
|
||||
"action": "click_if_exists",
|
||||
"target": "textarea[name*='memo'], input[placeholder*='메모']",
|
||||
"value": "E2E 수정된 제품검사 메모_{timestamp}",
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 필수 검증 #2: 수정 저장",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('저장')",
|
||||
"verify": {
|
||||
"url_maintained": true,
|
||||
"no_error_page": true,
|
||||
"api_call": "PUT /api/v1/quality/inspections/",
|
||||
"toast": "수정|완료|성공"
|
||||
},
|
||||
"expected": "수정 완료"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"개소: 테스트구역B",
|
||||
"메모: E2E 수정된"
|
||||
],
|
||||
"expected": "수정된 데이터 반영"
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 삭제 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('삭제')",
|
||||
"expected": {
|
||||
"confirm_dialog": true,
|
||||
"dialog_message": "삭제|정말"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 필수 검증 #6: 삭제 확인",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('확인'), button:has-text('삭제')",
|
||||
"verify": {
|
||||
"api_call": "DELETE /api/v1/quality/inspections/",
|
||||
"toast": "삭제|완료|성공",
|
||||
"redirect": "/quality/inspections"
|
||||
},
|
||||
"expected": "삭제 완료 및 목록 복귀"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 삭제 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"search": "E2E 수정된 제품검사",
|
||||
"expected": {
|
||||
"row_exists": false,
|
||||
"message": "테스트 제품검사가 목록에서 제거됨"
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/quality/inspections",
|
||||
"description": "제품검사 목록 조회"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"endpoint": "/api/v1/quality/inspections",
|
||||
"description": "제품검사 등록"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/quality/inspections/{id}",
|
||||
"description": "제품검사 상세 조회"
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"endpoint": "/api/v1/quality/inspections/{id}",
|
||||
"description": "제품검사 수정"
|
||||
},
|
||||
{
|
||||
"method": "DELETE",
|
||||
"endpoint": "/api/v1/quality/inspections/{id}",
|
||||
"description": "제품검사 삭제"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 2,
|
||||
"name": "등록/저장 버튼",
|
||||
"steps": [
|
||||
7,
|
||||
14
|
||||
],
|
||||
"criteria": "API 호출 + 성공 토스트 + 데이터 반영"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "검색/필터",
|
||||
"steps": [
|
||||
4
|
||||
],
|
||||
"criteria": "검색 기능 동작"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [
|
||||
2
|
||||
],
|
||||
"criteria": "제품검사 목록, 등록 버튼, 필터 존재"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "삭제 기능",
|
||||
"steps": [
|
||||
16,
|
||||
17,
|
||||
18
|
||||
],
|
||||
"criteria": "DELETE API + 목록에서 제거"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"onCreateFail": "모달 닫기",
|
||||
"onUpdateFail": "테스트 제품검사 수동 삭제 필요",
|
||||
"onDeleteFail": "테스트 제품검사 수동 삭제 필요",
|
||||
"cleanupRequired": "E2E_TEST_ 접두사 제품검사는 테스트 데이터"
|
||||
}
|
||||
}
|
||||
197
_backup_before_enhance/receiving-management.json
Normal file
197
_backup_before_enhance/receiving-management.json
Normal file
@@ -0,0 +1,197 @@
|
||||
{
|
||||
"enabled": true,
|
||||
"id": "receiving-management",
|
||||
"name": "입고관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "자재관리 > 입고관리 페이지의 입고 조회 및 상태별 필터링 기능을 테스트하는 E2E 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"url": "/material/receiving-management",
|
||||
"navigation": {
|
||||
"targetUrl": "/material/receiving-management",
|
||||
"urlPattern": "/material/receiving-management|/ko/material/receiving-management",
|
||||
"menuHints": ["입고관리", "입고 관리", "자재관리"]
|
||||
},
|
||||
"menuNavigation": {
|
||||
"level1": "자재관리",
|
||||
"level2": "입고관리",
|
||||
"expectedUrl": "/material/receiving-management",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"menuNavigationEnhanced": {
|
||||
"strategy": "scroll-and-search",
|
||||
"sidebar": {
|
||||
"scrollContainer": ".sidebar-scroll",
|
||||
"scrollStep": 200,
|
||||
"maxScrollAttempts": 5,
|
||||
"waitAfterScroll": 300
|
||||
},
|
||||
"level1": {
|
||||
"text": "자재관리",
|
||||
"expandable": true,
|
||||
"waitAfterClick": 500
|
||||
},
|
||||
"level2": {
|
||||
"text": "입고관리",
|
||||
"waitAfterClick": 300
|
||||
},
|
||||
"fallbackUrl": "/material/receiving-management",
|
||||
"expectedUrl": "/material/receiving-management"
|
||||
},
|
||||
"timeout": 90000,
|
||||
"tags": ["material", "receiving", "read-only"],
|
||||
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
|
||||
"steps": [
|
||||
{
|
||||
"id": "step-0",
|
||||
"name": "사이드바 메뉴 전체 펼치기",
|
||||
"description": "모두 펼치기 버튼을 클릭하여 전체 메뉴를 펼친 후 메뉴 탐색 준비",
|
||||
"actions": [
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "document.querySelector('.sidebar-scroll')?.scrollTo({top:0,behavior:'instant'})"
|
||||
},
|
||||
{ "type": "wait", "duration": 300 },
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "Array.from(document.querySelectorAll('button')).find(b => b.innerText?.includes('모두 펼치기'))?.click()"
|
||||
},
|
||||
{ "type": "wait", "duration": 2000 }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "step-1",
|
||||
"name": "자재관리 메뉴 진입",
|
||||
"description": "자재관리 > 입고관리 메뉴로 이동",
|
||||
"actions": [
|
||||
{
|
||||
"type": "scrollAndFind",
|
||||
"container": ".sidebar-scroll",
|
||||
"target": "자재관리",
|
||||
"scrollStep": 200,
|
||||
"maxAttempts": 5
|
||||
},
|
||||
{ "type": "click_if_exists", "target": "자재관리" },
|
||||
{ "type": "wait", "duration": 500 },
|
||||
{ "type": "click_if_exists", "target": "입고관리" }
|
||||
],
|
||||
"expect": {
|
||||
"url": "/material/receiving-management",
|
||||
"visible": ["입고 목록"]
|
||||
},
|
||||
"fallback": {
|
||||
"type": "navigate",
|
||||
"url": "/material/receiving-management"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-2",
|
||||
"name": "페이지 구조 확인",
|
||||
"description": "통계 카드와 테이블 구조 확인",
|
||||
"verify": {
|
||||
"visible": ["입고대기", "배송중", "검사대기", "금일입고"],
|
||||
"tableColumns": ["번호", "발주번호", "품목코드", "품목명", "공급업체", "발주수량", "입고수량", "LOT번호", "상태"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-3",
|
||||
"name": "필수 검증 #3: 상태 탭 필터 - 입고대기",
|
||||
"description": "입고대기 탭 클릭하여 필터링 확인",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "입고대기", "role": "tab" },
|
||||
{ "type": "wait", "duration": 300 }
|
||||
],
|
||||
"expect": {
|
||||
"tabActive": "입고대기",
|
||||
"dataFiltered": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-4",
|
||||
"name": "필수 검증 #3: 상태 탭 필터 - 입고완료",
|
||||
"description": "입고완료 탭 클릭하여 필터링 확인",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "입고완료", "role": "tab" },
|
||||
{ "type": "wait", "duration": 300 }
|
||||
],
|
||||
"expect": {
|
||||
"tabActive": "입고완료",
|
||||
"dataFiltered": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-5",
|
||||
"name": "전체 탭으로 복귀",
|
||||
"description": "전체 탭 클릭하여 모든 입고 표시",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "전체", "role": "tab" },
|
||||
{ "type": "wait", "duration": 300 }
|
||||
],
|
||||
"expect": {
|
||||
"tabActive": "전체",
|
||||
"allDataShown": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-6",
|
||||
"name": "빈 상태 확인",
|
||||
"description": "데이터가 없을 때 빈 상태 메시지 확인",
|
||||
"verify": {
|
||||
"emptyStateVisible": "검색 결과가 없습니다"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-7",
|
||||
"name": "통계 카드 값 확인",
|
||||
"description": "입고대기/배송중/검사대기/금일입고 카운트 표시 확인",
|
||||
"verify": {
|
||||
"statsCards": ["입고대기", "배송중", "검사대기", "금일입고"],
|
||||
"countsDisplayed": true
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
"assertions": [
|
||||
{
|
||||
"type": "url",
|
||||
"expected": "/material/receiving-management",
|
||||
"message": "입고관리 페이지에 머물러야 함"
|
||||
},
|
||||
{
|
||||
"type": "elementExists",
|
||||
"selector": "text=입고 목록",
|
||||
"message": "입고 목록 제목이 표시되어야 함"
|
||||
}
|
||||
],
|
||||
|
||||
"mandatoryVerifications": {
|
||||
"description": "E2E_TEST_CONFIG.md 기준 필수 검증 항목",
|
||||
"items": [
|
||||
{
|
||||
"id": 3,
|
||||
"name": "검색/필터",
|
||||
"trigger": "상태 탭 필터",
|
||||
"verification": "데이터 변화 확인",
|
||||
"failCondition": "필터 적용 후 데이터 무변화"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"notes": {
|
||||
"testScope": "입고 목록 조회 및 상태별 필터링 테스트",
|
||||
"pageType": "조회 전용 (발주 기반 입고 처리)",
|
||||
"statsCards": ["입고대기", "배송중", "검사대기", "금일입고"],
|
||||
"statusTabs": ["전체", "입고대기", "입고완료"],
|
||||
"tableColumns": ["번호", "발주번호", "품목코드", "품목명", "공급업체", "발주수량", "입고수량", "LOT번호", "상태"],
|
||||
"workflow": "발주 → 배송중 → 검사대기 → 입고완료",
|
||||
"prerequisites": "로그인된 사용자, 발주 데이터 존재 시 입고 가능"
|
||||
}
|
||||
}
|
||||
839
_backup_before_enhance/reference-box.json
Normal file
839
_backup_before_enhance/reference-box.json
Normal file
@@ -0,0 +1,839 @@
|
||||
{
|
||||
"id": "reference-box",
|
||||
"name": "참조함 E2E 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"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": [
|
||||
"참조함",
|
||||
"참조 함",
|
||||
"결재관리"
|
||||
]
|
||||
},
|
||||
"menuNavigation": {
|
||||
"level1": "결재관리",
|
||||
"level2": "참조함",
|
||||
"expectedUrl": "/ko/approval/reference",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"menuNavigationEnhanced": {
|
||||
"strategy": "scroll-and-search",
|
||||
"description": "사이드바를 스크롤하며 메뉴를 찾고 클릭하여 404를 방지",
|
||||
"level1": "결재관리",
|
||||
"level2": "참조함",
|
||||
"alternativeLevel1Names": [
|
||||
"결재관리",
|
||||
"결재 관리",
|
||||
"Approval",
|
||||
"전자결재"
|
||||
],
|
||||
"alternativeLevel2Names": [
|
||||
"참조함",
|
||||
"참조 함",
|
||||
"Reference",
|
||||
"참조문서",
|
||||
"CC문서"
|
||||
],
|
||||
"scrollConfig": {
|
||||
"sidebarSelector": "nav, aside, [role='navigation'], .sidebar, #sidebar",
|
||||
"menuItemSelector": "a, button, [role='menuitem'], [role='treeitem']",
|
||||
"scrollStep": 200,
|
||||
"maxScrollAttempts": 10,
|
||||
"scrollDelay": 300
|
||||
}
|
||||
},
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/approvals/reference",
|
||||
"description": "참조함 목록 조회",
|
||||
"queryParams": [
|
||||
"page",
|
||||
"per_page",
|
||||
"search",
|
||||
"is_read",
|
||||
"approval_type",
|
||||
"sort_by",
|
||||
"sort_dir"
|
||||
]
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"endpoint": "/api/v1/approvals/{id}/read",
|
||||
"description": "열람 처리"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"endpoint": "/api/v1/approvals/{id}/unread",
|
||||
"description": "미열람 처리"
|
||||
}
|
||||
],
|
||||
"steps": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": "사이드바 메뉴 전체 펼치기",
|
||||
"description": "모두 펼치기 버튼을 클릭하여 전체 메뉴를 펼친 후 메뉴 탐색 준비",
|
||||
"actions": [
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "document.querySelector('.sidebar-scroll')?.scrollTo({top:0,behavior:'instant'})"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 300
|
||||
},
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "Array.from(document.querySelectorAll('button')).find(b => b.innerText?.includes('모두 펼치기'))?.click()"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 2000
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"name": "2단계 메뉴 진입: 결재관리 > 참조함",
|
||||
"description": "사이드바를 스크롤하며 결재관리 > 참조함 메뉴를 찾아 클릭",
|
||||
"actions": [
|
||||
{
|
||||
"type": "scrollAndFind",
|
||||
"target": "결재관리",
|
||||
"alternativeTexts": [
|
||||
"결재관리",
|
||||
"결재 관리",
|
||||
"Approval",
|
||||
"전자결재"
|
||||
],
|
||||
"scrollContainer": "sidebar",
|
||||
"maxAttempts": 10,
|
||||
"description": "스크롤하며 결재관리 메뉴 찾기"
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "결재관리",
|
||||
"description": "결재관리 메뉴 클릭"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 500,
|
||||
"description": "서브메뉴 펼쳐지기 대기"
|
||||
},
|
||||
{
|
||||
"type": "scrollAndFind",
|
||||
"target": "참조함",
|
||||
"alternativeTexts": [
|
||||
"참조함",
|
||||
"참조 함",
|
||||
"Reference",
|
||||
"참조문서"
|
||||
],
|
||||
"scrollContainer": "submenu",
|
||||
"maxAttempts": 5,
|
||||
"description": "서브메뉴에서 참조함 찾기"
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "참조함",
|
||||
"description": "참조함 메뉴 클릭"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"target": "페이지 로드 완료",
|
||||
"timeout": 10000
|
||||
}
|
||||
],
|
||||
"verification": [
|
||||
"페이지 URL이 /approval/reference인지 확인",
|
||||
"페이지 제목 '참조함' 표시 확인",
|
||||
"설명 텍스트 '참조로 지정된 문서를 확인합니다.' 표시 확인",
|
||||
"통계 카드 3개 표시 (전체, 열람, 미열람)",
|
||||
"날짜 범위 선택기 표시 확인",
|
||||
"검색창 표시 확인 (placeholder: '제목, 기안자, 부서 검색...')",
|
||||
"탭 버튼 3개 표시 (전체, 열람, 미열람)",
|
||||
"필터 드롭다운 표시 (전체, 지출결의서, 품의서, 지출예상내역서)",
|
||||
"정렬 드롭다운 표시 (최신순, 오래된순, 기안일 오름차순, 기안일 내림차순)",
|
||||
"테이블 헤더 확인 (번호, 문서번호, 문서유형, 제목, 기안자, 기안일시, 상태)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "데이터 로딩 대기",
|
||||
"action": "wait",
|
||||
"duration": 3000,
|
||||
"verification": [
|
||||
"테이블에 데이터 행이 표시되는지 확인",
|
||||
"통계 카드에 숫자가 표시되는지 확인 (N건)",
|
||||
"'검색 결과가 없습니다' 메시지가 없는지 확인",
|
||||
"각 문서의 열람 상태 배지 표시 확인 (열람/미열람)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "통계 카드 데이터 확인",
|
||||
"action": "verify_element",
|
||||
"target": "[class*='card'], [class*='stat']",
|
||||
"verification": [
|
||||
"전체 건수 = 열람 건수 + 미열람 건수",
|
||||
"각 카드의 아이콘 표시 확인 (Files, Eye, EyeOff)",
|
||||
"스크린샷 촬영하여 초기 상태 저장"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "탭 전환 - 열람 탭",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('열람')",
|
||||
"verification": [
|
||||
"탭 활성화 상태 변경 확인",
|
||||
"테이블에 '열람' 상태 문서만 표시",
|
||||
"모든 행의 상태 배지가 '열람'인지 확인",
|
||||
"표시된 문서 개수가 통계 카드의 '열람' 건수와 일치"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "탭 전환 - 미열람 탭",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('미열람')",
|
||||
"verification": [
|
||||
"탭 활성화 상태 변경 확인",
|
||||
"테이블에 '미열람' 상태 문서만 표시",
|
||||
"모든 행의 상태 배지가 '미열람'인지 확인",
|
||||
"표시된 문서 개수가 통계 카드의 '미열람' 건수와 일치"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "탭 전환 - 전체 탭으로 복귀",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('전체')",
|
||||
"verification": [
|
||||
"탭 활성화 상태 변경 확인",
|
||||
"테이블에 모든 문서 표시 (열람 + 미열람)",
|
||||
"표시된 문서 개수가 통계 카드의 '전체' 건수와 일치"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "⚠️ 필수 검증: 검색 기능 - 기안자 검색",
|
||||
"actions": [
|
||||
{
|
||||
"type": "capture",
|
||||
"variable": "beforeSearchCount",
|
||||
"selector": "table tbody tr",
|
||||
"extract": "count",
|
||||
"description": "검색 전 문서 수 저장"
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "input[type='search'], input[placeholder*='검색']",
|
||||
"description": "검색창 존재 확인"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 1000,
|
||||
"description": "검색 결과 로딩 대기"
|
||||
},
|
||||
{
|
||||
"type": "capture",
|
||||
"variable": "afterSearchCount",
|
||||
"selector": "table tbody tr",
|
||||
"extract": "count",
|
||||
"description": "검색 후 문서 수 저장"
|
||||
}
|
||||
],
|
||||
"verify": {
|
||||
"searchApplied": true,
|
||||
"tableContains": "김철수",
|
||||
"dataChanged": "beforeSearchCount may differ from afterSearchCount"
|
||||
},
|
||||
"verification": [
|
||||
"검색창에 입력한 텍스트 표시 확인",
|
||||
"Enter 키 입력 또는 자동 검색 실행",
|
||||
"검색어를 포함한 문서만 필터링되어 표시",
|
||||
"검색 결과 건수 확인"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "7-1",
|
||||
"name": "검색 결과 데이터 검증",
|
||||
"description": "검색 결과의 모든 행이 검색어를 포함하는지 확인",
|
||||
"verify": {
|
||||
"allRowsContain": "김철수",
|
||||
"columnToCheck": "기안자"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "검색 초기화",
|
||||
"actions": [
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "input[type='search'], input[placeholder*='검색']",
|
||||
"description": "검색창 존재 확인"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 500
|
||||
},
|
||||
{
|
||||
"type": "capture",
|
||||
"variable": "afterClearCount",
|
||||
"selector": "table tbody tr",
|
||||
"extract": "count"
|
||||
}
|
||||
],
|
||||
"verify": {
|
||||
"dataRestored": "afterClearCount should equal beforeSearchCount"
|
||||
},
|
||||
"verification": [
|
||||
"전체 문서 목록 복원 확인",
|
||||
"원래 문서 개수로 복원"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "필터 기능 - 문서유형 선택",
|
||||
"action": "select",
|
||||
"target": "select, [role='combobox']",
|
||||
"value": "품의서",
|
||||
"verification": [
|
||||
"필터 드롭다운 값이 '품의서'로 변경",
|
||||
"테이블에 '품의서' 유형 문서만 표시",
|
||||
"모든 행의 문서유형 배지가 '품의서'인지 확인"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "필터 초기화",
|
||||
"action": "select",
|
||||
"target": "select, [role='combobox']",
|
||||
"value": "전체",
|
||||
"verification": [
|
||||
"전체 문서 목록 복원 확인"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "정렬 기능 - 오래된순",
|
||||
"action": "click_if_exists",
|
||||
"target": "select, [role='combobox']",
|
||||
"verification": [
|
||||
"정렬 드롭다운 값이 '오래된순'으로 변경",
|
||||
"테이블 데이터가 오래된 날짜부터 표시",
|
||||
"기안일시 컬럼 확인하여 오름차순 정렬 검증"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "정렬 초기화",
|
||||
"action": "click_if_exists",
|
||||
"target": "select, [role='combobox']",
|
||||
"verification": [
|
||||
"테이블 데이터가 최신 날짜부터 표시"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"name": "체크박스 - 단일 선택",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:first-child input[type='checkbox']",
|
||||
"verification": [
|
||||
"체크박스 선택 상태 확인",
|
||||
"'열람' 버튼 표시 확인",
|
||||
"'미열람' 버튼 표시 확인",
|
||||
"조건부 버튼이 헤더 영역에 표시됨"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"name": "체크박스 - 선택 해제",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:first-child input[type='checkbox']",
|
||||
"verification": [
|
||||
"체크박스 선택 해제 확인",
|
||||
"'열람' 및 '미열람' 버튼 사라짐 확인"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"name": "체크박스 - 다중 선택",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr input[type='checkbox']",
|
||||
"verification": [
|
||||
"2개 문서 선택 확인",
|
||||
"'열람' 및 '미열람' 버튼 표시 확인"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"name": "문서 상세 모달 - 열기",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:first-child td:nth-child(2)",
|
||||
"verification": [
|
||||
"문서 상세 모달 열림 확인",
|
||||
"⚠️ 필수 검증 #5: 목업 페이지 감지",
|
||||
"모달 제목 확인 (문서유형 + ' 상세')",
|
||||
"문서번호 표시 확인",
|
||||
"작성일자 표시 확인",
|
||||
"기안자 정보 표시 확인",
|
||||
"결재선 정보 표시 확인",
|
||||
"PDF/인쇄 버튼 존재 확인"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "16-pdf-1",
|
||||
"name": "⚠️ 필수 검증: PDF 다운로드 전 모달 스크린샷",
|
||||
"description": "PDF 생성 전 모달 상태를 스크린샷으로 캡처하여 CSS 문제 감지용 기준 이미지 확보",
|
||||
"prerequisite": "step-16의 문서 상세 모달이 열려있는 상태에서 실행",
|
||||
"actions": [
|
||||
{
|
||||
"type": "screenshot",
|
||||
"name": "pdf-preview-before-download-reference-box",
|
||||
"fullPage": false,
|
||||
"selector": "[role='dialog'], .modal, [data-state='open']",
|
||||
"savePath": "tests/e2e/results/hotfix/screenshots/",
|
||||
"description": "PDF 생성 대상 모달 전체 캡처"
|
||||
}
|
||||
],
|
||||
"verify": {
|
||||
"screenshotCaptured": true,
|
||||
"purpose": "PDF CSS 문제 감지를 위한 기준 이미지"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "16-pdf-2",
|
||||
"name": "⚠️ 필수 검증: PDF 다운로드 실행 및 파일 보관",
|
||||
"description": "PDF 다운로드 후 파일을 지정 폴더에 보관하여 수동 검증 가능하게 함",
|
||||
"actions": [
|
||||
{
|
||||
"type": "verify",
|
||||
"target": "PDF 버튼 존재",
|
||||
"selector": "button:has-text('PDF'), [aria-label*='PDF']",
|
||||
"description": "PDF 다운로드 버튼 존재 확인"
|
||||
},
|
||||
{
|
||||
"type": "expectResponse",
|
||||
"id": "pdf-download-response-reference-box",
|
||||
"urlPattern": "/api/v1/approvals/*/pdf",
|
||||
"description": "PDF 다운로드 API 응답 대기 설정"
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "PDF 버튼",
|
||||
"selector": "button:has-text('PDF')",
|
||||
"description": "PDF 다운로드 버튼 클릭"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 3000,
|
||||
"description": "PDF 생성 및 다운로드 대기"
|
||||
},
|
||||
{
|
||||
"type": "assertResponse",
|
||||
"id": "pdf-download-response-reference-box",
|
||||
"checks": {
|
||||
"status": 200,
|
||||
"contentType": "application/pdf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "saveDownloadedFile",
|
||||
"targetPath": "tests/e2e/results/hotfix/pdf-samples/",
|
||||
"fileNamePattern": "reference-box-{timestamp}.pdf",
|
||||
"description": "다운로드된 PDF 파일을 지정 폴더에 보관"
|
||||
}
|
||||
],
|
||||
"verify": {
|
||||
"apiSuccess": true,
|
||||
"fileDownloaded": true,
|
||||
"fileSaved": "tests/e2e/results/hotfix/pdf-samples/"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "16-pdf-3",
|
||||
"name": "⚠️ PDF 파일 유효성 검증",
|
||||
"description": "다운로드된 PDF 파일의 기본 유효성 검사",
|
||||
"actions": [
|
||||
{
|
||||
"type": "verifyDownloadedFile",
|
||||
"checks": {
|
||||
"fileExists": true,
|
||||
"fileSize": "> 1024",
|
||||
"pdfSignature": "%PDF-",
|
||||
"description": "PDF 파일 헤더 검증"
|
||||
}
|
||||
}
|
||||
],
|
||||
"verify": {
|
||||
"pdfValid": true,
|
||||
"minFileSize": "1KB 이상"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "16-pdf-4",
|
||||
"name": "📋 PDF 스타일 수동 확인 체크리스트",
|
||||
"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": "결재선"
|
||||
}
|
||||
],
|
||||
"outputFiles": {
|
||||
"screenshot": "tests/e2e/results/hotfix/screenshots/pdf-preview-before-download-reference-box-*.png",
|
||||
"pdfFile": "tests/e2e/results/hotfix/pdf-samples/reference-box-*.pdf"
|
||||
},
|
||||
"reportFlag": {
|
||||
"requiresManualReview": true,
|
||||
"message": "⚠️ PDF 스타일 수동 확인 필요 - 위 체크리스트 항목을 PDF 파일에서 직접 확인하세요"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"name": "문서 상세 모달 - 닫기",
|
||||
"action": "close_modal",
|
||||
"verification": [
|
||||
"모달 닫힘 확인",
|
||||
"원래 참조함 페이지로 복귀",
|
||||
"페이지 URL 유지 (/approval/reference)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"name": "미열람 탭으로 이동",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('미열람')",
|
||||
"verification": [
|
||||
"미열람 문서만 표시 확인",
|
||||
"모든 문서의 상태가 '미열람'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"name": "열람 처리 - 문서 선택",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:first-child input[type='checkbox']",
|
||||
"verification": [
|
||||
"체크박스 선택 확인",
|
||||
"'열람' 버튼 표시 확인"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"name": "열람 처리 - 확인 다이얼로그",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('열람')",
|
||||
"verification": [
|
||||
"확인 다이얼로그 표시",
|
||||
"다이얼로그 제목: '열람 처리'",
|
||||
"다이얼로그 메시지: '정말 1건을 열람 처리하시겠습니까?'",
|
||||
"취소 버튼 표시",
|
||||
"확인 버튼 표시"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"name": "열람 처리 - URL 안정성 검증 (⚠️ 필수 검증 #2)",
|
||||
"action": "save_url",
|
||||
"verification": [
|
||||
"⚠️ URL 변경 여부 확인 (변경되면 안됨)",
|
||||
"⚠️ 에러 페이지 텍스트 검색 ('페이지를 찾을 수 없습니다', '404', 'Not Found' 등)",
|
||||
"⚠️ 원래 페이지 요소 존재 확인 (테이블, 탭 등)",
|
||||
"성공 토스트 메시지 표시: '열람 처리 완료'",
|
||||
"토스트 설명: '열람 처리가 완료되었습니다.'",
|
||||
"다이얼로그 자동 닫힘",
|
||||
"체크박스 선택 해제",
|
||||
"미열람 탭의 문서 개수 1개 감소"
|
||||
],
|
||||
"criticalCheck": {
|
||||
"type": "URL_STABILITY",
|
||||
"beforeURL": "/approval/reference",
|
||||
"afterURL": "/approval/reference",
|
||||
"errorPageTexts": [
|
||||
"페이지를 찾을 수 없습니다",
|
||||
"404",
|
||||
"Not Found",
|
||||
"서버 에러",
|
||||
"500"
|
||||
],
|
||||
"successToast": "열람 처리 완료"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"name": "열람 처리 후 데이터 검증",
|
||||
"action": "verify_detail",
|
||||
"verification": [
|
||||
"미열람 탭에서 처리된 문서 제거 확인",
|
||||
"통계 카드의 '미열람' 건수 1개 감소 (실시간 업데이트)",
|
||||
"통계 카드의 '열람' 건수 1개 증가 (실시간 업데이트)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 23,
|
||||
"name": "열람 탭으로 이동하여 검증",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('열람')",
|
||||
"verification": [
|
||||
"열람 탭에 방금 처리한 문서 표시 확인",
|
||||
"해당 문서의 상태 배지가 '열람'으로 변경"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 24,
|
||||
"name": "미열람 처리 - 문서 선택",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:first-child input[type='checkbox']",
|
||||
"verification": [
|
||||
"체크박스 선택 확인",
|
||||
"'미열람' 버튼 표시 확인"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 25,
|
||||
"name": "미열람 처리 - 확인 다이얼로그",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('미열람')",
|
||||
"verification": [
|
||||
"확인 다이얼로그 표시",
|
||||
"다이얼로그 제목: '미열람 처리'",
|
||||
"다이얼로그 메시지: '정말 1건을 미열람 처리하시겠습니까?'",
|
||||
"취소 버튼 표시",
|
||||
"확인 버튼 표시"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 26,
|
||||
"name": "미열람 처리 - URL 안정성 검증 (⚠️ 필수 검증 #2)",
|
||||
"action": "save_url",
|
||||
"verification": [
|
||||
"⚠️ URL 변경 여부 확인 (변경되면 안됨)",
|
||||
"⚠️ 에러 페이지 텍스트 검색",
|
||||
"성공 토스트 메시지 표시: '미열람 처리 완료'",
|
||||
"토스트 설명: '미열람 처리가 완료되었습니다.'",
|
||||
"다이얼로그 자동 닫힘",
|
||||
"체크박스 선택 해제",
|
||||
"열람 탭의 문서 개수 1개 감소"
|
||||
],
|
||||
"criticalCheck": {
|
||||
"type": "URL_STABILITY",
|
||||
"beforeURL": "/approval/reference",
|
||||
"afterURL": "/approval/reference",
|
||||
"errorPageTexts": [
|
||||
"페이지를 찾을 수 없습니다",
|
||||
"404",
|
||||
"Not Found",
|
||||
"서버 에러",
|
||||
"500"
|
||||
],
|
||||
"successToast": "미열람 처리 완료"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 27,
|
||||
"name": "미열람 처리 후 데이터 검증",
|
||||
"action": "verify_detail",
|
||||
"verification": [
|
||||
"열람 탭에서 처리된 문서 제거 확인",
|
||||
"통계 카드의 '열람' 건수 1개 감소 (실시간 업데이트)",
|
||||
"통계 카드의 '미열람' 건수 1개 증가 (실시간 업데이트)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 28,
|
||||
"name": "일괄 열람 처리 - 다중 선택",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('미열람')",
|
||||
"verification": [
|
||||
"2개 문서 선택 확인",
|
||||
"'열람' 버튼 표시 확인"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 29,
|
||||
"name": "일괄 열람 처리 - 실행",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('열람')",
|
||||
"verification": [
|
||||
"다이얼로그 메시지: '정말 2건을 열람 처리하시겠습니까?'",
|
||||
"확인 버튼 클릭",
|
||||
"⚠️ URL 안정성 확인",
|
||||
"성공 토스트 메시지 표시",
|
||||
"미열람 탭에서 2개 문서 제거",
|
||||
"통계 카드 업데이트 (미열람 -2, 열람 +2)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 30,
|
||||
"name": "날짜 범위 선택기 테스트",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('당월')",
|
||||
"verification": [
|
||||
"시작일과 종료일이 당월로 변경",
|
||||
"데이터 재로드 확인 (로딩 인디케이터 또는 데이터 변화)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 31,
|
||||
"name": "페이지네이션 테스트",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('2')",
|
||||
"verification": [
|
||||
"페이지네이션 컨트롤 표시 확인",
|
||||
"2페이지 버튼 클릭",
|
||||
"페이지 번호 변경 확인",
|
||||
"새로운 데이터 로드 확인"
|
||||
],
|
||||
"conditional": "문서 개수가 20개 이상인 경우에만 실행"
|
||||
},
|
||||
{
|
||||
"id": 32,
|
||||
"name": "Console 로그 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body",
|
||||
"verification": [
|
||||
"ERROR 로그 없는지 확인",
|
||||
"WARNING 로그 확인 (접근성 경고 등)",
|
||||
"Network 요청 확인 (GET /api/v1/approvals/reference)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 33,
|
||||
"name": "최종 통계 확인",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('전체')",
|
||||
"verification": [
|
||||
"전체 문서 목록 표시",
|
||||
"통계 카드 수치 정확성 확인",
|
||||
"전체 = 열람 + 미열람 수식 성립",
|
||||
"스크린샷 촬영하여 최종 상태 저장"
|
||||
]
|
||||
}
|
||||
],
|
||||
"mandatoryVerifications": [
|
||||
{
|
||||
"id": "VERIFICATION_2",
|
||||
"name": "등록/저장 동작 검증 (URL 안정성)",
|
||||
"appliesTo": [
|
||||
"Step 21",
|
||||
"Step 26",
|
||||
"Step 29"
|
||||
],
|
||||
"requirements": [
|
||||
"URL 변경 여부 확인 (처리 전 URL과 처리 후 URL 비교)",
|
||||
"에러 페이지 텍스트 검색 ('페이지를 찾을 수 없습니다', '404', 'Not Found', '서버 에러', '500')",
|
||||
"원래 페이지 요소 존재 확인 (테이블, 탭, 통계 카드 등)",
|
||||
"성공 토스트 메시지 표시 확인",
|
||||
"다이얼로그 자동 닫힘 확인"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "VERIFICATION_5",
|
||||
"name": "목업/미완성 페이지 감지",
|
||||
"appliesTo": [
|
||||
"Step 1",
|
||||
"Step 16"
|
||||
],
|
||||
"requirements": [
|
||||
"입력 필드 존재 여부 확인 (검색창 등)",
|
||||
"동작하는 버튼 확인 (최소 2개 버튼 클릭 테스트)",
|
||||
"API 호출 확인 (Console LOG만 아닌 실제 Network Request)",
|
||||
"데이터 변경 가능 여부 확인 (열람/미열람 처리 등)",
|
||||
"목업 판정 기준: 2개 이상 항목 해당 시 목업으로 판정"
|
||||
]
|
||||
}
|
||||
],
|
||||
"bugReportTemplate": {
|
||||
"priority": "Critical/High/Medium/Low",
|
||||
"component": "ReferenceBox",
|
||||
"affectedArea": "react",
|
||||
"relatedFiles": [
|
||||
"C:\\Users\\codeb\\react\\src\\components\\approval\\ReferenceBox\\index.tsx",
|
||||
"C:\\Users\\codeb\\react\\src\\components\\approval\\ReferenceBox\\actions.ts",
|
||||
"C:\\Users\\codeb\\react\\src\\components\\approval\\ReferenceBox\\types.ts"
|
||||
],
|
||||
"changeApprovalPolicy": "✅ 즉시 가능 / ⚠️ 컨펌 필요 / 🔴 금지"
|
||||
},
|
||||
"testData": {
|
||||
"searchKeyword": "김철수",
|
||||
"dateRange": {
|
||||
"startDate": "2025-01-01",
|
||||
"endDate": "2026-01-31"
|
||||
}
|
||||
},
|
||||
"notes": [
|
||||
"참조함은 열람/미열람 상태 관리가 핵심 기능입니다.",
|
||||
"결재함과 달리 승인/반려 기능은 없고, 열람/미열람 처리만 가능합니다.",
|
||||
"통계 카드의 실시간 업데이트 확인이 중요합니다.",
|
||||
"URL 안정성 검증(필수 검증 #2)을 모든 처리 동작에서 수행해야 합니다.",
|
||||
"문서 상세 모달은 읽기 전용(mode='reference')으로 표시됩니다."
|
||||
]
|
||||
}
|
||||
274
_backup_before_enhance/sales-client.json
Normal file
274
_backup_before_enhance/sales-client.json
Normal file
@@ -0,0 +1,274 @@
|
||||
{
|
||||
"enabled": true,
|
||||
"id": "sales-client",
|
||||
"name": "판매거래처관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": [
|
||||
"error",
|
||||
"fail",
|
||||
"timeout",
|
||||
"404",
|
||||
"500",
|
||||
"blocked"
|
||||
]
|
||||
},
|
||||
"description": "판매관리 > 거래처관리 메뉴의 판매 거래처 CRUD 기능 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "판매관리",
|
||||
"level2": "거래처관리",
|
||||
"expectedUrl": "/sales/client-management-sales-admin",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"testData": {
|
||||
"create": {
|
||||
"clientName": "E2E_TEST_판매처_{timestamp}",
|
||||
"businessNumber": "987-65-43210",
|
||||
"representative": "테스트 대표"
|
||||
}
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 판매관리 > 거래처관리",
|
||||
"action": "menu_navigate",
|
||||
"level1": "판매관리",
|
||||
"level2": "거래처관리",
|
||||
"expected": {
|
||||
"url_contains": "/sales/client",
|
||||
"visible": [
|
||||
"거래처관리",
|
||||
"거래처"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"거래처 목록 표시",
|
||||
"거래처 등록 버튼 존재",
|
||||
"검색 기능 존재"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "거래처 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
"거래처명 컬럼",
|
||||
"사업자번호 컬럼",
|
||||
"대표자 컬럼",
|
||||
"연락처 컬럼"
|
||||
],
|
||||
"expected": "거래처 테이블 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 거래처 등록 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('등록'), button:has-text('추가'), button:has-text('신규')",
|
||||
"expected": {
|
||||
"modal_open": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 거래처명 입력",
|
||||
"action": "fill",
|
||||
"target": "input[name*='name'], input[placeholder*='거래처명']",
|
||||
"value": "E2E_TEST_판매처_{timestamp}",
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 사업자번호 입력",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[name*='business'], input[placeholder*='사업자']",
|
||||
"value": "987-65-43210",
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 대표자명 입력",
|
||||
"action": "fill",
|
||||
"target": "input[name*='representative'], input[placeholder*='대표']",
|
||||
"value": "테스트 대표",
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 필수 검증 #2: 거래처 저장",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('저장'), button:has-text('등록'), button:has-text('확인')",
|
||||
"verify": {
|
||||
"url_maintained": true,
|
||||
"no_error_page": true,
|
||||
"api_call": "POST /api/v1/sales/clients",
|
||||
"toast": "등록|저장|완료|성공"
|
||||
},
|
||||
"expected": "거래처 등록 완료"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 등록된 거래처 검색",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[type='search'], input[placeholder*='검색']",
|
||||
"value": "E2E_TEST_판매처",
|
||||
"submit": true
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 등록된 거래처 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"E2E_TEST_판매처 목록에 표시"
|
||||
],
|
||||
"expected": "등록된 거래처 확인"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 거래처 상세 조회",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:has-text('E2E_TEST')",
|
||||
"expected": {
|
||||
"detail_view": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 거래처 수정 모드 진입",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('수정'), button:has-text('편집')",
|
||||
"expected": {
|
||||
"edit_mode": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 대표자명 수정",
|
||||
"action": "fill",
|
||||
"target": "input[name*='representative'], input[placeholder*='대표']",
|
||||
"value": "수정된 대표",
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 거래처 저장",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('저장'), button:has-text('확인')",
|
||||
"verify": {
|
||||
"api_call": "PUT /api/v1/sales/clients",
|
||||
"toast": "수정|저장|완료|성공"
|
||||
},
|
||||
"expected": "거래처 수정 완료"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 거래처 삭제",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('삭제'), button:has-text('제거')",
|
||||
"expected": {
|
||||
"confirm_dialog": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 삭제 확인",
|
||||
"action": "click_if_exists",
|
||||
"target": "[role='alertdialog'] button:has-text('확인'), [role='dialog'] button:has-text('삭제')",
|
||||
"verify": {
|
||||
"api_call": "DELETE /api/v1/sales/clients",
|
||||
"toast": "삭제|제거|완료|성공"
|
||||
},
|
||||
"expected": "거래처 삭제 완료"
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 삭제 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"E2E_TEST_판매처 목록에서 제거"
|
||||
],
|
||||
"expected": "거래처 삭제 반영"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"name": "엑셀 다운로드 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"엑셀 다운로드 버튼 존재"
|
||||
],
|
||||
"expected": "엑셀 다운로드 기능 표시"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/sales/clients",
|
||||
"description": "거래처 목록 조회"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"endpoint": "/api/v1/sales/clients",
|
||||
"description": "거래처 등록"
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"endpoint": "/api/v1/sales/clients/:id",
|
||||
"description": "거래처 수정"
|
||||
},
|
||||
{
|
||||
"method": "DELETE",
|
||||
"endpoint": "/api/v1/sales/clients/:id",
|
||||
"description": "거래처 삭제"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 2,
|
||||
"name": "저장 버튼",
|
||||
"steps": [
|
||||
8,
|
||||
14
|
||||
],
|
||||
"criteria": "API 호출 + 성공 토스트 + 데이터 반영"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [
|
||||
2
|
||||
],
|
||||
"criteria": "거래처 목록, 등록 버튼, 검색 기능 존재"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"onCreateFail": "등록 모달 닫고 재시도",
|
||||
"onUpdateFail": "페이지 새로고침 후 재시도",
|
||||
"onDeleteFail": "수동 삭제 필요",
|
||||
"cleanupRequired": "E2E_TEST_판매처_* 패턴 데이터 삭제"
|
||||
}
|
||||
}
|
||||
726
_backup_before_enhance/sales-management.json
Normal file
726
_backup_before_enhance/sales-management.json
Normal file
@@ -0,0 +1,726 @@
|
||||
{
|
||||
"enabled": true,
|
||||
"id": "sales-management",
|
||||
"name": "매출관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": [
|
||||
"error",
|
||||
"fail",
|
||||
"timeout",
|
||||
"404",
|
||||
"500",
|
||||
"blocked"
|
||||
]
|
||||
},
|
||||
"description": "회계관리 > 매출관리 메뉴의 매출등록, 계정과목 저장, 품목 동적 추가, 자동계산 로직 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "회계관리",
|
||||
"level2": "매출관리",
|
||||
"expectedUrl": "/ko/accounting/sales",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"navigation": {
|
||||
"targetUrl": "/accounting/sales",
|
||||
"urlPattern": "/accounting/sales|/ko/accounting/sales",
|
||||
"menuHints": [
|
||||
"매출관리",
|
||||
"매출",
|
||||
"회계관리"
|
||||
]
|
||||
},
|
||||
"menuNavigationEnhanced": {
|
||||
"strategy": "scroll-and-search",
|
||||
"sidebarSelector": ".sidebar-scroll, [class*='sidebar'], nav[class*='menu']",
|
||||
"scrollConfig": {
|
||||
"scrollStep": 200,
|
||||
"maxScrollAttempts": 10,
|
||||
"scrollDelay": 300
|
||||
},
|
||||
"level1": {
|
||||
"text": "회계관리",
|
||||
"selectors": [
|
||||
"//span[contains(text(),'회계관리')]",
|
||||
"//div[contains(@class,'menu')]//span[text()='회계관리']",
|
||||
"[data-menu='accounting']"
|
||||
]
|
||||
},
|
||||
"level2": {
|
||||
"text": "매출관리",
|
||||
"selectors": [
|
||||
"//a[contains(text(),'매출관리')]",
|
||||
"//span[contains(text(),'매출관리')]",
|
||||
"[href*='/accounting/sales']"
|
||||
]
|
||||
},
|
||||
"fallbackUrl": "/ko/accounting/sales"
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": "사이드바 메뉴 전체 펼치기",
|
||||
"description": "모두 펼치기 버튼을 클릭하여 전체 메뉴를 펼친 후 메뉴 탐색 준비",
|
||||
"actions": [
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "document.querySelector('.sidebar-scroll')?.scrollTo({top:0,behavior:'instant'})"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 300
|
||||
},
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "Array.from(document.querySelectorAll('button')).find(b => b.innerText?.includes('모두 펼치기'))?.click()"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 2000
|
||||
}
|
||||
],
|
||||
"expected": "사이드바 전체 메뉴가 펼쳐짐"
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"name": "로그인",
|
||||
"action": "click_if_exists",
|
||||
"target": "form, [role=\"dialog\"], .modal",
|
||||
"expected": "로그인 성공 후 메인 페이지 이동"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "2단계 메뉴 진입: 회계관리 > 매출관리",
|
||||
"description": "스크롤하며 회계관리 메뉴를 찾아 클릭 후 매출관리 진입",
|
||||
"navigationPattern": "scrollAndFind",
|
||||
"actions": [
|
||||
{
|
||||
"type": "scrollAndFind",
|
||||
"description": "사이드바 스크롤하며 회계관리 메뉴 찾기",
|
||||
"scrollContainer": ".sidebar-scroll, [class*='sidebar']",
|
||||
"targetText": "회계관리",
|
||||
"scrollStep": 200,
|
||||
"maxAttempts": 10
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "회계관리",
|
||||
"selectors": [
|
||||
"//span[contains(text(),'회계관리')]",
|
||||
"//div[contains(@class,'menu')]//span[text()='회계관리']"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 500
|
||||
},
|
||||
{
|
||||
"type": "scrollAndFind",
|
||||
"description": "확장된 서브메뉴에서 매출관리 찾기",
|
||||
"scrollContainer": ".sidebar-scroll, [class*='sidebar']",
|
||||
"targetText": "매출관리",
|
||||
"scrollStep": 100,
|
||||
"maxAttempts": 5
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "매출관리",
|
||||
"selectors": [
|
||||
"//a[contains(text(),'매출관리')]",
|
||||
"//span[contains(text(),'매출관리')]",
|
||||
"[href*='/accounting/sales']"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"target": "페이지 로드 완료"
|
||||
}
|
||||
],
|
||||
"fallback": {
|
||||
"type": "navigate",
|
||||
"url": "/ko/accounting/sales"
|
||||
},
|
||||
"expected": {
|
||||
"url": "/ko/accounting/sales",
|
||||
"pageTitle": "매출관리",
|
||||
"elements": [
|
||||
"매출 등록 버튼",
|
||||
"테이블"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"입력 필드 존재 (검색창, 날짜 선택)",
|
||||
"동작하는 버튼 존재 (매출 등록, 엑셀 다운로드)",
|
||||
"테이블 데이터 표시",
|
||||
"API 호출 확인"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "목록 페이지 - 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
"체크박스 컬럼",
|
||||
"No. 컬럼",
|
||||
"매출번호 컬럼",
|
||||
"거래처명 컬럼",
|
||||
"매출일 컬럼",
|
||||
"매출유형 컬럼",
|
||||
"공급가액 컬럼",
|
||||
"부가세 컬럼",
|
||||
"합계금액 컬럼",
|
||||
"계산서 컬럼",
|
||||
"명세서 컬럼"
|
||||
],
|
||||
"expected": "테이블 컬럼 구조 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "계정과목명 드롭박스 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"계정과목명 라벨 존재",
|
||||
"드롭박스(Select) 존재",
|
||||
"저장 버튼 존재"
|
||||
],
|
||||
"expected": "계정과목 선택 UI 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "계정과목명 드롭박스 옵션 확인",
|
||||
"action": "click_if_exists",
|
||||
"target": "accountSubject",
|
||||
"checks": [
|
||||
"미설정 옵션",
|
||||
"제품매출 옵션",
|
||||
"상품매출 옵션",
|
||||
"기타매출 옵션"
|
||||
],
|
||||
"expected": "계정과목 옵션 목록 표시"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "체크박스 선택 (계정과목 저장용)",
|
||||
"action": "click_if_exists",
|
||||
"target": "first_row",
|
||||
"expected": "첫 번째 행 체크박스 선택됨"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "계정과목 변경 - 제품매출 선택",
|
||||
"action": "click_if_exists",
|
||||
"target": "accountSubject",
|
||||
"value": "product",
|
||||
"expected": "계정과목이 '제품매출'로 변경됨"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "필수 검증 #2: 계정과목 저장 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "저장",
|
||||
"checks": [
|
||||
"확인 다이얼로그 표시",
|
||||
"선택된 항목 수 표시",
|
||||
"계정과목명 표시"
|
||||
],
|
||||
"expected": "저장 확인 다이얼로그 표시"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "저장 확인 다이얼로그 - 확인 클릭",
|
||||
"action": "click_if_exists",
|
||||
"checks": [
|
||||
"API 호출 확인 (PUT /api/v1/sales/batch-update-account)",
|
||||
"성공 토스트 메시지",
|
||||
"URL 유지 확인"
|
||||
],
|
||||
"expected": "계정과목 저장 성공"
|
||||
},
|
||||
{
|
||||
"id": "10-1",
|
||||
"name": "⚠️ 필수 검증: 계정과목명 변경 데이터 반영 확인",
|
||||
"action": "verify_data_update",
|
||||
"target": "first_row",
|
||||
"checks": [
|
||||
"선택한 행의 매출유형 컬럼 값 확인",
|
||||
"변경 전 값과 비교 (예: 기타 매출 → 제품 매출)",
|
||||
"페이지 새로고침 후에도 변경된 값 유지 확인",
|
||||
"API 응답과 UI 표시값 일치 확인"
|
||||
],
|
||||
"expected": "선택한 행의 매출유형이 '제품매출'로 실제 변경되어야 함",
|
||||
"note": "토스트 성공 메시지만으로 PASS 판정 불가. 실제 데이터 변경 확인 필수!"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "매출 등록 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "매출 등록",
|
||||
"expected": "매출 등록 페이지로 이동 (/ko/accounting/sales?mode=new)"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "매출 등록 페이지 - URL 확인",
|
||||
"action": "verify_url",
|
||||
"target": "/ko/accounting/sales?mode=new",
|
||||
"expected": "매출 등록 페이지 URL 정상"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"name": "매출 등록 페이지 - 기본정보 섹션 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"매출번호 필드 (자동생성, readonly)",
|
||||
"매출일 필드 (DatePicker)",
|
||||
"거래처명 드롭박스",
|
||||
"매출유형 드롭박스"
|
||||
],
|
||||
"expected": "기본정보 섹션 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"name": "매출번호 자동생성 확인",
|
||||
"action": "verify_field",
|
||||
"target": "salesNo",
|
||||
"checks": [
|
||||
"값이 자동 생성됨 (예: S-2026-0001)",
|
||||
"readonly 상태"
|
||||
],
|
||||
"expected": "매출번호 자동생성 확인"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"name": "거래처명 드롭박스 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "vendorId",
|
||||
"expected": "거래처 목록 표시"
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"name": "거래처명 선택",
|
||||
"action": "click_if_exists",
|
||||
"target": "vendorId",
|
||||
"value": "first_available",
|
||||
"expected": "거래처가 선택됨"
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"name": "매출유형 드롭박스 확인",
|
||||
"action": "click_if_exists",
|
||||
"target": "salesType",
|
||||
"checks": [
|
||||
"외상매출 옵션",
|
||||
"제품매출 옵션",
|
||||
"상품매출 옵션",
|
||||
"부품매출 옵션",
|
||||
"공사매출 옵션",
|
||||
"임대매출 옵션",
|
||||
"기타매출 옵션"
|
||||
],
|
||||
"expected": "매출유형 옵션 목록 표시"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"name": "매출유형 선택 - 제품매출",
|
||||
"action": "click_if_exists",
|
||||
"target": "salesType",
|
||||
"value": "product",
|
||||
"expected": "매출유형이 '제품매출'로 선택됨"
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"name": "품목정보 섹션 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"품목 정보 제목",
|
||||
"품목 추가 버튼 (+)",
|
||||
"품목 테이블 헤더 (품목명, 수량, 단가, 공급가액, 부가세, 적요)",
|
||||
"기본 품목 행 1개 존재"
|
||||
],
|
||||
"expected": "품목정보 섹션 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"name": "품목 동적 추가 - 추가 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "품목 추가",
|
||||
"expected": "새로운 품목 행 추가됨"
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"name": "품목 행 개수 확인 (2개)",
|
||||
"action": "verify_row_count",
|
||||
"target": "items_table",
|
||||
"expected": "품목 행이 2개로 증가"
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"name": "품목 동적 삭제 - 두 번째 행 삭제",
|
||||
"action": "click_if_exists",
|
||||
"target": "remove_item_row_2",
|
||||
"expected": "두 번째 품목 행 삭제됨"
|
||||
},
|
||||
{
|
||||
"id": 23,
|
||||
"name": "품목 행 개수 확인 (1개)",
|
||||
"action": "verify_row_count",
|
||||
"target": "items_table",
|
||||
"expected": "품목 행이 1개로 감소"
|
||||
},
|
||||
{
|
||||
"id": 24,
|
||||
"name": "품목명 입력",
|
||||
"action": "click_if_exists",
|
||||
"target": "items[0].itemName",
|
||||
"value": "테스트 품목",
|
||||
"expected": "품목명 입력됨"
|
||||
},
|
||||
{
|
||||
"id": 25,
|
||||
"name": "수량 입력",
|
||||
"action": "click_if_exists",
|
||||
"target": "items[0].quantity",
|
||||
"value": "10",
|
||||
"expected": "수량 입력됨"
|
||||
},
|
||||
{
|
||||
"id": 26,
|
||||
"name": "단가 입력",
|
||||
"action": "click_if_exists",
|
||||
"target": "items[0].unitPrice",
|
||||
"value": "50000",
|
||||
"expected": "단가 입력됨"
|
||||
},
|
||||
{
|
||||
"id": 27,
|
||||
"name": "자동계산 검증 - 공급가액",
|
||||
"action": "verify_calculated_value",
|
||||
"target": "items[0].supplyAmount",
|
||||
"formula": "quantity * unitPrice",
|
||||
"expectedValue": "500000",
|
||||
"checks": [
|
||||
"수량(10) × 단가(50000) = 공급가액(500,000)",
|
||||
"자동으로 계산되어 표시됨"
|
||||
],
|
||||
"expected": "공급가액이 500,000원으로 자동 계산됨"
|
||||
},
|
||||
{
|
||||
"id": 28,
|
||||
"name": "자동계산 검증 - 부가세",
|
||||
"action": "verify_calculated_value",
|
||||
"target": "items[0].vat",
|
||||
"formula": "supplyAmount * 0.1",
|
||||
"expectedValue": "50000",
|
||||
"checks": [
|
||||
"공급가액(500,000) × 10% = 부가세(50,000)",
|
||||
"자동으로 계산되어 표시됨"
|
||||
],
|
||||
"expected": "부가세가 50,000원으로 자동 계산됨"
|
||||
},
|
||||
{
|
||||
"id": 29,
|
||||
"name": "적요 입력 (선택사항)",
|
||||
"action": "click_if_exists",
|
||||
"target": "items[0].note",
|
||||
"value": "테스트 적요",
|
||||
"expected": "적요 입력됨"
|
||||
},
|
||||
{
|
||||
"id": 30,
|
||||
"name": "세금계산서 발행 Switch 확인",
|
||||
"action": "verify_elements",
|
||||
"target": "taxInvoice_section",
|
||||
"checks": [
|
||||
"세금계산서 발행 라벨",
|
||||
"Switch 버튼 존재",
|
||||
"기본값 OFF 상태"
|
||||
],
|
||||
"expected": "세금계산서 발행 Switch 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 31,
|
||||
"name": "세금계산서 발행 Switch ON",
|
||||
"action": "click_if_exists",
|
||||
"target": "taxInvoiceSwitch",
|
||||
"value": "on",
|
||||
"expected": "세금계산서 발행 Switch가 ON으로 변경됨"
|
||||
},
|
||||
{
|
||||
"id": 32,
|
||||
"name": "세금계산서 발행 Switch OFF",
|
||||
"action": "click_if_exists",
|
||||
"target": "taxInvoiceSwitch",
|
||||
"value": "off",
|
||||
"expected": "세금계산서 발행 Switch가 OFF로 변경됨"
|
||||
},
|
||||
{
|
||||
"id": 33,
|
||||
"name": "거래명세서 발행 Switch 확인",
|
||||
"action": "verify_elements",
|
||||
"target": "transactionStatement_section",
|
||||
"checks": [
|
||||
"거래명세서 발행 라벨",
|
||||
"Switch 버튼 존재",
|
||||
"기본값 OFF 상태"
|
||||
],
|
||||
"expected": "거래명세서 발행 Switch 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 34,
|
||||
"name": "거래명세서 발행 Switch ON",
|
||||
"action": "click_if_exists",
|
||||
"target": "transactionStatementSwitch",
|
||||
"value": "on",
|
||||
"expected": "거래명세서 발행 Switch가 ON으로 변경됨"
|
||||
},
|
||||
{
|
||||
"id": 35,
|
||||
"name": "거래명세서 발행 Switch OFF",
|
||||
"action": "click_if_exists",
|
||||
"target": "transactionStatementSwitch",
|
||||
"value": "off",
|
||||
"expected": "거래명세서 발행 Switch가 OFF로 변경됨"
|
||||
},
|
||||
{
|
||||
"id": 36,
|
||||
"name": "합계 금액 확인",
|
||||
"action": "verify_totals",
|
||||
"checks": [
|
||||
"총 공급가액: 500,000원",
|
||||
"총 부가세: 50,000원",
|
||||
"총 합계금액: 550,000원"
|
||||
],
|
||||
"expected": "합계 금액 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 37,
|
||||
"name": "취소 버튼 동작 테스트",
|
||||
"action": "click_if_exists",
|
||||
"target": "취소",
|
||||
"expected": "취소 확인 다이얼로그 또는 목록 페이지로 이동"
|
||||
},
|
||||
{
|
||||
"id": 38,
|
||||
"name": "취소 확인 - 목록 페이지 복귀",
|
||||
"action": "verify_url",
|
||||
"target": "/ko/accounting/sales",
|
||||
"expected": "매출 목록 페이지로 복귀"
|
||||
},
|
||||
{
|
||||
"id": 39,
|
||||
"name": "다시 매출 등록 페이지 진입",
|
||||
"action": "click_if_exists",
|
||||
"target": "매출 등록",
|
||||
"expected": "매출 등록 페이지로 이동"
|
||||
},
|
||||
{
|
||||
"id": 40,
|
||||
"name": "등록 테스트용 데이터 입력 - 거래처 선택",
|
||||
"action": "click_if_exists",
|
||||
"target": "vendorId",
|
||||
"value": "first_available",
|
||||
"expected": "거래처 선택됨"
|
||||
},
|
||||
{
|
||||
"id": 41,
|
||||
"name": "등록 테스트용 데이터 입력 - 매출유형",
|
||||
"action": "click_if_exists",
|
||||
"target": "salesType",
|
||||
"value": "product",
|
||||
"expected": "매출유형 선택됨"
|
||||
},
|
||||
{
|
||||
"id": 42,
|
||||
"name": "등록 테스트용 데이터 입력 - 품목명",
|
||||
"action": "click_if_exists",
|
||||
"target": "items[0].itemName",
|
||||
"value": "E2E 테스트 품목",
|
||||
"expected": "품목명 입력됨"
|
||||
},
|
||||
{
|
||||
"id": 43,
|
||||
"name": "등록 테스트용 데이터 입력 - 수량",
|
||||
"action": "click_if_exists",
|
||||
"target": "items[0].quantity",
|
||||
"value": "5",
|
||||
"expected": "수량 입력됨"
|
||||
},
|
||||
{
|
||||
"id": 44,
|
||||
"name": "등록 테스트용 데이터 입력 - 단가",
|
||||
"action": "click_if_exists",
|
||||
"target": "items[0].unitPrice",
|
||||
"value": "100000",
|
||||
"expected": "단가 입력됨"
|
||||
},
|
||||
{
|
||||
"id": 45,
|
||||
"name": "필수 검증 #2: 등록 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "등록",
|
||||
"checks": [
|
||||
"버튼 클릭 전 URL 저장",
|
||||
"API 호출 확인 (POST /api/v1/sales)",
|
||||
"에러 페이지 감지",
|
||||
"성공 토스트 메시지 확인"
|
||||
],
|
||||
"expected": "매출 등록 완료"
|
||||
},
|
||||
{
|
||||
"id": 46,
|
||||
"name": "등록 성공 확인 - 토스트 메시지",
|
||||
"action": "verify_toast",
|
||||
"target": "매출이 등록되었습니다",
|
||||
"expected": "성공 토스트 메시지 표시"
|
||||
},
|
||||
{
|
||||
"id": 47,
|
||||
"name": "등록 성공 확인 - 목록 페이지 이동",
|
||||
"action": "verify_url",
|
||||
"target": "/ko/accounting/sales",
|
||||
"expected": "매출 목록 페이지로 이동"
|
||||
},
|
||||
{
|
||||
"id": 48,
|
||||
"name": "등록된 매출 목록 확인",
|
||||
"action": "verify_table_data",
|
||||
"checks": [
|
||||
"신규 등록된 매출이 목록에 표시됨",
|
||||
"품목명: E2E 테스트 품목",
|
||||
"공급가액: 500,000원"
|
||||
],
|
||||
"expected": "등록된 매출이 목록에 표시됨"
|
||||
},
|
||||
{
|
||||
"id": 49,
|
||||
"name": "거래처 미선택 시 유효성 검증 테스트",
|
||||
"action": "navigate",
|
||||
"target": "/ko/accounting/sales?mode=new",
|
||||
"expected": "매출 등록 페이지 이동"
|
||||
},
|
||||
{
|
||||
"id": 50,
|
||||
"name": "거래처 미선택 상태에서 등록 시도",
|
||||
"action": "click_if_exists",
|
||||
"target": "등록",
|
||||
"expected": "유효성 검증 실패 - 경고 메시지"
|
||||
},
|
||||
{
|
||||
"id": 51,
|
||||
"name": "유효성 검증 메시지 확인",
|
||||
"action": "verify_toast",
|
||||
"target": "거래처를 선택해주세요",
|
||||
"type": "warning",
|
||||
"expected": "거래처 선택 요청 경고 메시지 표시"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "파일 다운로드 (엑셀)",
|
||||
"steps": [],
|
||||
"criteria": "이 시나리오에서는 테스트하지 않음 (별도 시나리오)"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "등록/저장 버튼",
|
||||
"steps": [
|
||||
9,
|
||||
10,
|
||||
45,
|
||||
46,
|
||||
47
|
||||
],
|
||||
"criteria": "계정과목 저장 + 매출 등록 시 API 호출 + 성공 토스트 + URL 유지/이동 확인"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "검색/필터",
|
||||
"steps": [],
|
||||
"criteria": "이 시나리오에서는 테스트하지 않음 (등록 중심 테스트)"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "모달 등록 완료",
|
||||
"steps": [
|
||||
9,
|
||||
10
|
||||
],
|
||||
"criteria": "계정과목 저장 확인 다이얼로그 → 확인 클릭 → 저장 완료"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "⚠️ 계정과목명 변경 데이터 반영 (필수)",
|
||||
"steps": [
|
||||
"10-1"
|
||||
],
|
||||
"criteria": "저장 후 실제 테이블 데이터가 변경되었는지 확인. 토스트만 확인하면 불충분!",
|
||||
"priority": "critical",
|
||||
"knownBug": {
|
||||
"bugId": "BUG-SALES-20260115-001",
|
||||
"status": "OPEN",
|
||||
"description": "성공 토스트 표시되나 실제 데이터 미변경"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [
|
||||
3
|
||||
],
|
||||
"criteria": "입력 필드, 동작 버튼, API 호출 확인"
|
||||
}
|
||||
],
|
||||
"testData": {
|
||||
"vendor": "첫 번째 사용 가능한 거래처",
|
||||
"salesType": "product",
|
||||
"item": {
|
||||
"itemName": "E2E 테스트 품목",
|
||||
"quantity": 5,
|
||||
"unitPrice": 100000
|
||||
},
|
||||
"calculatedValues": {
|
||||
"supplyAmount": 500000,
|
||||
"vat": 50000,
|
||||
"totalAmount": 550000
|
||||
}
|
||||
},
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/sales",
|
||||
"description": "매출 목록 조회"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/clients",
|
||||
"description": "거래처 목록 조회 (드롭박스용)"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"endpoint": "/api/v1/sales",
|
||||
"description": "매출 등록"
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"endpoint": "/api/v1/sales/batch-update-account",
|
||||
"description": "계정과목 일괄 변경"
|
||||
}
|
||||
],
|
||||
"skipTests": [
|
||||
{
|
||||
"feature": "삭제 기능",
|
||||
"reason": "사용자 요청에 따라 삭제 테스트 제외"
|
||||
}
|
||||
]
|
||||
}
|
||||
372
_backup_before_enhance/sales-order.json
Normal file
372
_backup_before_enhance/sales-order.json
Normal file
@@ -0,0 +1,372 @@
|
||||
{
|
||||
"enabled": true,
|
||||
"id": "sales-order",
|
||||
"name": "수주관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": [
|
||||
"error",
|
||||
"fail",
|
||||
"timeout",
|
||||
"404",
|
||||
"500",
|
||||
"blocked"
|
||||
]
|
||||
},
|
||||
"description": "판매관리 > 수주관리 메뉴의 수주 조회/등록/수정/삭제 전체 CRUD 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "판매관리",
|
||||
"level2": "수주관리",
|
||||
"expectedUrl": "/sales/order-management-sales",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"testData": {
|
||||
"create": {
|
||||
"clientName": "E2E_TEST_거래처",
|
||||
"itemName": "테스트품목",
|
||||
"quantity": "200",
|
||||
"unitPrice": "15000",
|
||||
"deliveryDate": "2026-02-15",
|
||||
"memo": "E2E 자동화 테스트 수주"
|
||||
},
|
||||
"update": {
|
||||
"quantity": "250",
|
||||
"memo": "E2E 수정된 수주 메모"
|
||||
}
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 판매관리 > 수주관리",
|
||||
"action": "menu_navigate",
|
||||
"level1": "판매관리",
|
||||
"level2": "수주관리",
|
||||
"expected": {
|
||||
"url_contains": "/sales/order",
|
||||
"visible": [
|
||||
"수주관리",
|
||||
"수주"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"수주 목록 표시",
|
||||
"수주 등록 버튼 존재",
|
||||
"검색/필터 기능 존재"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "수주 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
"수주번호 컬럼",
|
||||
"거래처 컬럼",
|
||||
"품목 컬럼",
|
||||
"수량 컬럼",
|
||||
"금액 컬럼",
|
||||
"상태 컬럼"
|
||||
],
|
||||
"expected": "수주 테이블 컬럼 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "검색 기능 테스트",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[placeholder*='검색']",
|
||||
"value": "테스트",
|
||||
"expected": {
|
||||
"data_filtered": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 수주 등록 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('등록'), button:has-text('수주 등록'), button:has-text('추가')",
|
||||
"expected": {
|
||||
"modal_or_page": true,
|
||||
"title": "수주 등록"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 수주 정보 입력",
|
||||
"action": "fill_form",
|
||||
"fields": [
|
||||
{
|
||||
"name": "거래처",
|
||||
"type": "select",
|
||||
"value": "E2E_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": "타임스탬프로 고유성 보장"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 필수 검증 #2: 등록 저장",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('저장'), button:has-text('등록')",
|
||||
"verify": {
|
||||
"url_maintained": true,
|
||||
"no_error_page": true,
|
||||
"api_call": "POST /api/v1/sales-orders",
|
||||
"toast": "등록|완료|성공"
|
||||
},
|
||||
"expected": "수주 등록 완료"
|
||||
},
|
||||
{
|
||||
"id": "7-modal-close",
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 모달 닫기 확인",
|
||||
"action": "close_modal_if_open",
|
||||
"expected": "모달 닫힘"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 등록 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"search": "E2E 자동화 테스트 수주",
|
||||
"expected": {
|
||||
"row_exists": true,
|
||||
"contains": [
|
||||
"E2E",
|
||||
"200",
|
||||
"3,000,000"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 수주 상세 페이지 진입",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:has-text('E2E')",
|
||||
"expected": {
|
||||
"url_contains": "/sales/order",
|
||||
"visible": [
|
||||
"수주 상세",
|
||||
"수정",
|
||||
"삭제"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"거래처: E2E_TEST_거래처",
|
||||
"수량: 200",
|
||||
"금액: 3,000,000",
|
||||
"납기일: 2026-02-15"
|
||||
],
|
||||
"expected": "입력한 데이터와 일치"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 모드 진입",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('수정')",
|
||||
"expected": {
|
||||
"url_contains": "mode=edit",
|
||||
"fields_editable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수량 수정",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[name*='quantity'], input[placeholder*='수량']",
|
||||
"value": "250",
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 메모 수정",
|
||||
"action": "click_if_exists",
|
||||
"target": "textarea[name*='memo'], input[placeholder*='메모']",
|
||||
"value": "E2E 수정된 수주 메모_{timestamp}",
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 필수 검증 #2: 수정 저장",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('저장')",
|
||||
"verify": {
|
||||
"url_maintained": true,
|
||||
"no_error_page": true,
|
||||
"api_call": "PUT /api/v1/sales-orders/",
|
||||
"toast": "수정|완료|성공"
|
||||
},
|
||||
"expected": "수정 완료"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"수량: 250",
|
||||
"금액: 3,750,000"
|
||||
],
|
||||
"expected": "수정된 데이터 반영"
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 삭제 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('삭제')",
|
||||
"expected": {
|
||||
"confirm_dialog": true,
|
||||
"dialog_message": "삭제|정말"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 필수 검증 #6: 삭제 확인",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('확인'), button:has-text('삭제')",
|
||||
"verify": {
|
||||
"api_call": "DELETE /api/v1/sales-orders/",
|
||||
"toast": "삭제|완료|성공",
|
||||
"redirect": "/sales/order"
|
||||
},
|
||||
"expected": "삭제 완료 및 목록 복귀"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 삭제 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"search": "E2E 수정된 수주",
|
||||
"expected": {
|
||||
"row_exists": false,
|
||||
"message": "테스트 수주가 목록에서 제거됨"
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/sales-orders",
|
||||
"description": "수주 목록 조회"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"endpoint": "/api/v1/sales-orders",
|
||||
"description": "수주 등록"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/sales-orders/{id}",
|
||||
"description": "수주 상세 조회"
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"endpoint": "/api/v1/sales-orders/{id}",
|
||||
"description": "수주 수정"
|
||||
},
|
||||
{
|
||||
"method": "DELETE",
|
||||
"endpoint": "/api/v1/sales-orders/{id}",
|
||||
"description": "수주 삭제"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 2,
|
||||
"name": "등록/저장 버튼",
|
||||
"steps": [
|
||||
7,
|
||||
14
|
||||
],
|
||||
"criteria": "API 호출 + 성공 토스트 + 데이터 반영"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "검색/필터",
|
||||
"steps": [
|
||||
4
|
||||
],
|
||||
"criteria": "검색 기능 동작"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [
|
||||
2
|
||||
],
|
||||
"criteria": "수주 목록, 등록 버튼, 필터 존재"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "삭제 기능",
|
||||
"steps": [
|
||||
16,
|
||||
17,
|
||||
18
|
||||
],
|
||||
"criteria": "DELETE API + 목록에서 제거"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"onCreateFail": "모달 닫기",
|
||||
"onUpdateFail": "테스트 수주 수동 삭제 필요",
|
||||
"onDeleteFail": "테스트 수주 수동 삭제 필요",
|
||||
"cleanupRequired": "E2E_TEST_ 접두사 수주는 테스트 데이터"
|
||||
}
|
||||
}
|
||||
154
_backup_before_enhance/sales-pricing.json
Normal file
154
_backup_before_enhance/sales-pricing.json
Normal file
@@ -0,0 +1,154 @@
|
||||
{
|
||||
"enabled": true,
|
||||
"id": "sales-pricing",
|
||||
"name": "단가관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "판매관리 > 단가관리 메뉴의 단가 목록 조회 및 UI 검증 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "판매관리",
|
||||
"level2": "단가관리",
|
||||
"expectedUrl": "/sales/pricing-management",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 판매관리 > 단가관리",
|
||||
"action": "menu_navigate",
|
||||
"level1": "판매관리",
|
||||
"level2": "단가관리",
|
||||
"expected": {
|
||||
"url_contains": "/sales/pricing",
|
||||
"visible": ["단가관리", "단가"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"단가 목록 표시",
|
||||
"단가 등록 버튼 존재",
|
||||
"검색 기능 존재"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "단가 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
"품목 컬럼",
|
||||
"거래처 컬럼",
|
||||
"단가 컬럼",
|
||||
"적용일 컬럼"
|
||||
],
|
||||
"expected": "단가 테이블 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "단가 UI 요소 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"등록 버튼 존재",
|
||||
"검색 입력 필드",
|
||||
"단가 목록"
|
||||
],
|
||||
"expected": "단가 UI 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 단가 목록 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"단가 목록 데이터 표시됨"
|
||||
],
|
||||
"expected": "단가 목록 정상"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 첫 번째 단가 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:first-child"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 단가 상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"단가 상세 정보 표시"
|
||||
],
|
||||
"expected": "단가 상세 정보 확인"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "상세 모달/페이지 닫기",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('닫기'), button:has-text('목록'), button:has-text('Close')"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "모달 닫기 확인",
|
||||
"action": "close_modal_if_open",
|
||||
"expected": "모달 닫힘"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "목록 복귀 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
"단가 목록 표시"
|
||||
],
|
||||
"expected": "목록 복귀 확인"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "엑셀 다운로드 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"엑셀 다운로드 버튼 존재 여부"
|
||||
],
|
||||
"expected": "엑셀 다운로드 기능 확인"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "단가관리 페이지 최종 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"단가 목록 구조 정상",
|
||||
"등록 버튼 존재"
|
||||
],
|
||||
"expected": "단가관리 페이지 정상"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/sales/pricing",
|
||||
"description": "단가 목록 조회"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"criteria": "단가 목록, 등록 버튼, 검색 기능 존재"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"note": "READ-only 패턴으로 안정성 우선"
|
||||
}
|
||||
}
|
||||
364
_backup_before_enhance/sales-quotation.json
Normal file
364
_backup_before_enhance/sales-quotation.json
Normal file
@@ -0,0 +1,364 @@
|
||||
{
|
||||
"enabled": true,
|
||||
"id": "sales-quotation",
|
||||
"name": "견적관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": [
|
||||
"error",
|
||||
"fail",
|
||||
"timeout",
|
||||
"404",
|
||||
"500",
|
||||
"blocked"
|
||||
]
|
||||
},
|
||||
"description": "판매관리 > 견적관리 메뉴의 견적서 조회/등록/수정/삭제 전체 CRUD 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "판매관리",
|
||||
"level2": "견적관리",
|
||||
"expectedUrl": "/sales/quote-management",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"testData": {
|
||||
"create": {
|
||||
"clientName": "E2E_TEST_거래처",
|
||||
"itemName": "테스트품목",
|
||||
"quantity": "100",
|
||||
"unitPrice": "10000",
|
||||
"memo": "E2E 자동화 테스트 견적"
|
||||
},
|
||||
"update": {
|
||||
"quantity": "150",
|
||||
"memo": "E2E 수정된 견적 메모"
|
||||
}
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 판매관리 > 견적관리",
|
||||
"action": "menu_navigate",
|
||||
"level1": "판매관리",
|
||||
"level2": "견적관리",
|
||||
"expected": {
|
||||
"url_contains": "/sales/quote",
|
||||
"visible": [
|
||||
"견적관리",
|
||||
"견적"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"견적 목록 표시",
|
||||
"견적 등록 버튼 존재",
|
||||
"검색/필터 기능 존재"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "견적 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
"견적번호 컬럼",
|
||||
"거래처 컬럼",
|
||||
"품목 컬럼",
|
||||
"금액 컬럼",
|
||||
"상태 컬럼",
|
||||
"작성일 컬럼"
|
||||
],
|
||||
"expected": "견적 테이블 컬럼 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "검색 기능 테스트",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[placeholder*='검색']",
|
||||
"value": "테스트",
|
||||
"expected": {
|
||||
"data_filtered": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 견적 등록 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('등록'), button:has-text('견적 등록'), button:has-text('추가')",
|
||||
"expected": {
|
||||
"modal_or_page": true,
|
||||
"title": "견적 등록"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 견적 정보 입력",
|
||||
"action": "fill_form",
|
||||
"fields": [
|
||||
{
|
||||
"name": "거래처",
|
||||
"type": "select",
|
||||
"value": "E2E_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": "타임스탬프로 고유성 보장"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 필수 검증 #2: 등록 저장",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('저장'), button:has-text('등록')",
|
||||
"verify": {
|
||||
"url_maintained": true,
|
||||
"no_error_page": true,
|
||||
"api_call": "POST /api/v1/quotations",
|
||||
"toast": "등록|완료|성공"
|
||||
},
|
||||
"expected": "견적 등록 완료"
|
||||
},
|
||||
{
|
||||
"id": "7-modal-close",
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 모달 닫기 확인",
|
||||
"action": "close_modal_if_open",
|
||||
"expected": "모달 닫힘"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 등록 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"search": "E2E 자동화 테스트 견적",
|
||||
"expected": {
|
||||
"row_exists": true,
|
||||
"contains": [
|
||||
"E2E",
|
||||
"1,000,000"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 견적 상세 페이지 진입",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:has-text('E2E')",
|
||||
"expected": {
|
||||
"url_contains": "/sales/quote",
|
||||
"visible": [
|
||||
"견적 상세",
|
||||
"수정",
|
||||
"삭제"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"거래처: E2E_TEST_거래처",
|
||||
"수량: 100",
|
||||
"금액: 1,000,000"
|
||||
],
|
||||
"expected": "입력한 데이터와 일치"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 모드 진입",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('수정')",
|
||||
"expected": {
|
||||
"url_contains": "mode=edit",
|
||||
"fields_editable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수량 수정",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[name*='quantity'], input[placeholder*='수량']",
|
||||
"value": "150",
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 메모 수정",
|
||||
"action": "click_if_exists",
|
||||
"target": "textarea[name*='memo'], input[placeholder*='메모']",
|
||||
"value": "E2E 수정된 견적 메모_{timestamp}",
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 필수 검증 #2: 수정 저장",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('저장')",
|
||||
"verify": {
|
||||
"url_maintained": true,
|
||||
"no_error_page": true,
|
||||
"api_call": "PUT /api/v1/quotations/",
|
||||
"toast": "수정|완료|성공"
|
||||
},
|
||||
"expected": "수정 완료"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"수량: 150",
|
||||
"금액: 1,500,000"
|
||||
],
|
||||
"expected": "수정된 데이터 반영"
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 삭제 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('삭제')",
|
||||
"expected": {
|
||||
"confirm_dialog": true,
|
||||
"dialog_message": "삭제|정말"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 필수 검증 #6: 삭제 확인",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('확인'), button:has-text('삭제')",
|
||||
"verify": {
|
||||
"api_call": "DELETE /api/v1/quotations/",
|
||||
"toast": "삭제|완료|성공",
|
||||
"redirect": "/sales/quote"
|
||||
},
|
||||
"expected": "삭제 완료 및 목록 복귀"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 삭제 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"search": "E2E 수정된 견적",
|
||||
"expected": {
|
||||
"row_exists": false,
|
||||
"message": "테스트 견적이 목록에서 제거됨"
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/quotations",
|
||||
"description": "견적 목록 조회"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"endpoint": "/api/v1/quotations",
|
||||
"description": "견적 등록"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/quotations/{id}",
|
||||
"description": "견적 상세 조회"
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"endpoint": "/api/v1/quotations/{id}",
|
||||
"description": "견적 수정"
|
||||
},
|
||||
{
|
||||
"method": "DELETE",
|
||||
"endpoint": "/api/v1/quotations/{id}",
|
||||
"description": "견적 삭제"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 2,
|
||||
"name": "등록/저장 버튼",
|
||||
"steps": [
|
||||
7,
|
||||
14
|
||||
],
|
||||
"criteria": "API 호출 + 성공 토스트 + 데이터 반영"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "검색/필터",
|
||||
"steps": [
|
||||
4
|
||||
],
|
||||
"criteria": "검색 기능 동작"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [
|
||||
2
|
||||
],
|
||||
"criteria": "견적 목록, 등록 버튼, 필터 존재"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "삭제 기능",
|
||||
"steps": [
|
||||
16,
|
||||
17,
|
||||
18
|
||||
],
|
||||
"criteria": "DELETE API + 목록에서 제거"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"onCreateFail": "모달 닫기",
|
||||
"onUpdateFail": "테스트 견적 수동 삭제 필요",
|
||||
"onDeleteFail": "테스트 견적 수동 삭제 필요",
|
||||
"cleanupRequired": "E2E_TEST_ 접두사 견적은 테스트 데이터"
|
||||
}
|
||||
}
|
||||
157
_backup_before_enhance/settings-account.json
Normal file
157
_backup_before_enhance/settings-account.json
Normal file
@@ -0,0 +1,157 @@
|
||||
{
|
||||
"id": "settings-account",
|
||||
"name": "계정정보 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "설정 > 계정정보 메뉴의 계정 정보 조회 및 UI 검증 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "설정",
|
||||
"level2": "계정정보",
|
||||
"expectedUrl": "/settings/account-info",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 설정 > 계정정보",
|
||||
"action": "menu_navigate",
|
||||
"level1": "설정",
|
||||
"level2": "계정정보",
|
||||
"expected": {
|
||||
"url_contains": "/settings/account",
|
||||
"visible": ["계정정보", "프로필"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"계정 정보 폼 표시",
|
||||
"프로필 이미지 영역 존재",
|
||||
"수정 버튼 존재"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "계정 정보 폼 구조 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"사용자명 표시",
|
||||
"이메일 표시",
|
||||
"연락처 표시",
|
||||
"프로필 이미지 영역"
|
||||
],
|
||||
"expected": "계정 정보 폼 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 현재 계정 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"사용자명 표시됨",
|
||||
"이메일 표시됨",
|
||||
"연락처 표시됨"
|
||||
],
|
||||
"expected": "현재 계정 정보 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 프로필 수정 모드 진입",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('수정'), button:has-text('편집')",
|
||||
"expected": {
|
||||
"edit_mode": true,
|
||||
"fields_editable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 표시 이름 필드 확인",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[name*='displayName'], input[name*='name'], input[placeholder*='이름']"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 연락처 필드 확인",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[name*='phone'], input[type='tel']"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 필수 검증 #2: 프로필 저장",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('저장'), button:has-text('확인')",
|
||||
"verify": {
|
||||
"url_maintained": true,
|
||||
"no_error_page": true,
|
||||
"toast": "저장|수정|완료|성공"
|
||||
},
|
||||
"expected": "프로필 저장 완료"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 저장 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"프로필 정보 표시됨"
|
||||
],
|
||||
"expected": "프로필 정보 표시"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "비밀번호 변경 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"비밀번호 변경 버튼 존재"
|
||||
],
|
||||
"expected": "비밀번호 변경 버튼 표시"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "비밀번호 변경 모달 열기",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('비밀번호 변경'), button:has-text('비밀번호')"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "비밀번호 변경 모달 닫기",
|
||||
"action": "close_modal_if_open",
|
||||
"expected": "모달 닫힘"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/users/profile",
|
||||
"description": "프로필 정보 조회"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"criteria": "계정 정보 폼, 수정 버튼 존재"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"onUpdateFail": "페이지 새로고침으로 원래 값 복원",
|
||||
"note": "READ-only 패턴으로 안정성 우선"
|
||||
}
|
||||
}
|
||||
161
_backup_before_enhance/settings-attendance.json
Normal file
161
_backup_before_enhance/settings-attendance.json
Normal file
@@ -0,0 +1,161 @@
|
||||
{
|
||||
"id": "settings-attendance",
|
||||
"name": "근태설정 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "설정 > 근태설정 메뉴의 근태 정책 조회 및 UI 검증 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "설정",
|
||||
"level2": "근태설정",
|
||||
"expectedUrl": "/settings/attendance-settings",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 설정 > 근태설정",
|
||||
"action": "menu_navigate",
|
||||
"level1": "설정",
|
||||
"level2": "근태설정",
|
||||
"expected": {
|
||||
"url_contains": "/settings/attendance",
|
||||
"visible": ["근태설정", "근태"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"근태 설정 폼 표시",
|
||||
"출퇴근 시간 설정 가능",
|
||||
"저장 버튼 존재"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "근태 설정 폼 구조 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"지각 기준 시간 설정",
|
||||
"조퇴 기준 시간 설정",
|
||||
"자동 퇴근 처리 설정",
|
||||
"출퇴근 인정 범위"
|
||||
],
|
||||
"expected": "근태 설정 폼 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 현재 근태 설정 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"지각 기준 표시",
|
||||
"조퇴 기준 표시",
|
||||
"자동 퇴근 설정 표시"
|
||||
],
|
||||
"expected": "현재 근태 설정 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 지각 기준 필드 확인",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[name*='late'], input[placeholder*='지각']"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 조퇴 기준 필드 확인",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[name*='early'], input[placeholder*='조퇴']"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 자동 퇴근 시간 필드 확인",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[name*='autoCheckout'], input[type='time']"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 필수 검증 #2: 근태 설정 저장",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('저장'), button:has-text('적용')",
|
||||
"verify": {
|
||||
"url_maintained": true,
|
||||
"no_error_page": true,
|
||||
"toast": "저장|적용|완료|성공"
|
||||
},
|
||||
"expected": "근태 설정 저장 완료"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 저장 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"근태 설정 정보 표시됨"
|
||||
],
|
||||
"expected": "설정 정보 표시"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "위치 기반 출퇴근 설정 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"GPS 출퇴근 사용 여부",
|
||||
"출퇴근 가능 위치 설정"
|
||||
],
|
||||
"expected": "위치 기반 설정 표시"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "근태 이상 알림 설정 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"지각 알림 설정",
|
||||
"무단결근 알림 설정"
|
||||
],
|
||||
"expected": "알림 설정 표시"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "부서별 근태 설정 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"부서별 설정 가능"
|
||||
],
|
||||
"expected": "부서별 설정 표시"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/settings/attendance",
|
||||
"description": "근태 설정 조회"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"criteria": "근태 설정 폼, 저장 버튼 존재"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"onUpdateFail": "페이지 새로고침으로 원래 값 복원",
|
||||
"note": "READ-only 패턴으로 안정성 우선"
|
||||
}
|
||||
}
|
||||
153
_backup_before_enhance/settings-bank-account.json
Normal file
153
_backup_before_enhance/settings-bank-account.json
Normal file
@@ -0,0 +1,153 @@
|
||||
{
|
||||
"id": "settings-bank-account",
|
||||
"name": "계좌관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "설정 > 계좌관리 메뉴의 계좌 목록 조회 및 UI 검증 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "설정",
|
||||
"level2": "계좌관리",
|
||||
"expectedUrl": "/settings/accounts",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 설정 > 계좌관리",
|
||||
"action": "menu_navigate",
|
||||
"level1": "설정",
|
||||
"level2": "계좌관리",
|
||||
"expected": {
|
||||
"url_contains": "/settings/accounts",
|
||||
"visible": ["계좌관리", "계좌"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"계좌 목록 표시",
|
||||
"계좌 등록 버튼 존재",
|
||||
"검색/필터 기능 존재"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "계좌 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
"은행명 컬럼",
|
||||
"계좌번호 컬럼",
|
||||
"예금주 컬럼",
|
||||
"계좌유형 컬럼"
|
||||
],
|
||||
"expected": "계좌 테이블 컬럼 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "검색 기능 확인",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[placeholder*='검색']",
|
||||
"expected": {
|
||||
"search_available": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "계좌 등록 버튼 확인",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('등록'), button:has-text('계좌 등록'), button:has-text('추가')",
|
||||
"expected": {
|
||||
"modal_or_page": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "등록 폼/모달 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"은행명 입력 필드",
|
||||
"계좌번호 입력 필드",
|
||||
"예금주 입력 필드"
|
||||
],
|
||||
"expected": "계좌 등록 폼 표시"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "등록 모달 닫기",
|
||||
"action": "close_modal_if_open",
|
||||
"expected": "모달 닫힘"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 계좌 목록 데이터 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"계좌 목록 데이터 표시됨"
|
||||
],
|
||||
"expected": "계좌 목록 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 첫 번째 행 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:first-child"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 계좌 상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"계좌 상세 정보 표시"
|
||||
],
|
||||
"expected": "계좌 상세 정보 확인"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "상세 모달 닫기",
|
||||
"action": "close_modal_if_open",
|
||||
"expected": "모달 닫힘"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "계좌 목록 최종 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"계좌 목록 구조 정상",
|
||||
"등록 버튼 존재"
|
||||
],
|
||||
"expected": "계좌관리 페이지 정상"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/bank-accounts",
|
||||
"description": "계좌 목록 조회"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"criteria": "계좌 목록, 등록 버튼, 필터 존재"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"note": "READ-only 패턴으로 안정성 우선"
|
||||
}
|
||||
}
|
||||
190
_backup_before_enhance/settings-company.json
Normal file
190
_backup_before_enhance/settings-company.json
Normal file
@@ -0,0 +1,190 @@
|
||||
{
|
||||
"id": "settings-company",
|
||||
"name": "회사정보 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "설정 > 회사정보 메뉴의 회사 정보 조회/수정 기능 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "설정",
|
||||
"level2": "회사정보",
|
||||
"expectedUrl": "/company-info",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"testData": {
|
||||
"update": {
|
||||
"companyPhone": "02-1234-5678",
|
||||
"companyFax": "02-1234-5679"
|
||||
}
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 설정 > 회사정보",
|
||||
"action": "menu_navigate",
|
||||
"level1": "설정",
|
||||
"level2": "회사정보",
|
||||
"expected": {
|
||||
"url_contains": "/company",
|
||||
"visible": ["회사정보", "회사"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"회사 정보 폼 표시",
|
||||
"사업자등록번호 표시",
|
||||
"수정 버튼 존재"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "회사 정보 폼 구조 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"회사명 표시",
|
||||
"사업자등록번호 표시",
|
||||
"대표자명 표시",
|
||||
"주소 표시",
|
||||
"연락처 표시"
|
||||
],
|
||||
"expected": "회사 정보 폼 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 현재 회사 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"회사명 표시됨",
|
||||
"사업자등록번호 표시됨",
|
||||
"대표자명 표시됨"
|
||||
],
|
||||
"expected": "현재 회사 정보 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 회사 정보 수정 모드 진입",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('수정'), button:has-text('편집')",
|
||||
"expected": {
|
||||
"edit_mode": true,
|
||||
"fields_editable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 회사 전화번호 수정",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[name*='phone'], input[placeholder*='전화']"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 팩스번호 수정",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[name*='fax'], input[placeholder*='팩스']"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 필수 검증 #2: 회사 정보 저장",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('저장'), button:has-text('확인')",
|
||||
"verify": {
|
||||
"url_maintained": true,
|
||||
"no_error_page": true,
|
||||
"api_call": "PUT /api/v1/company",
|
||||
"toast": "저장|수정|완료|성공"
|
||||
},
|
||||
"expected": "회사 정보 저장 완료"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 저장 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"전화번호: 02-1234-5678",
|
||||
"팩스: 02-1234-5679"
|
||||
],
|
||||
"expected": "수정된 정보 반영"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "로고 이미지 영역 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"회사 로고 표시",
|
||||
"로고 변경 버튼"
|
||||
],
|
||||
"expected": "로고 영역 표시"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "사업자등록증 영역 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"사업자등록증 첨부",
|
||||
"파일 업로드 버튼"
|
||||
],
|
||||
"expected": "첨부 영역 표시"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "법인등록번호 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"법인등록번호 표시"
|
||||
],
|
||||
"expected": "법인등록번호 표시"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/company",
|
||||
"description": "회사 정보 조회"
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"endpoint": "/api/v1/company",
|
||||
"description": "회사 정보 수정"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"endpoint": "/api/v1/company/logo",
|
||||
"description": "회사 로고 업로드"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 2,
|
||||
"name": "저장 버튼",
|
||||
"steps": [8],
|
||||
"criteria": "API 호출 + 성공 토스트 + 정보 반영"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"criteria": "회사 정보 폼, 수정 버튼 존재"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"onUpdateFail": "페이지 새로고침으로 원래 값 복원",
|
||||
"note": "회사 정보 수정은 관리자 권한이 필요할 수 있음"
|
||||
}
|
||||
}
|
||||
196
_backup_before_enhance/settings-notification.json
Normal file
196
_backup_before_enhance/settings-notification.json
Normal file
@@ -0,0 +1,196 @@
|
||||
{
|
||||
"id": "settings-notification",
|
||||
"name": "알림설정 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "설정 > 알림설정 메뉴의 알림 설정 조회/수정/저장 기능 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "설정",
|
||||
"level2": "알림설정",
|
||||
"expectedUrl": "/settings/notification-settings",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"testData": {
|
||||
"update": {
|
||||
"emailNotification": true,
|
||||
"pushNotification": true,
|
||||
"approvalNotification": true,
|
||||
"attendanceNotification": false
|
||||
}
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 설정 > 알림설정",
|
||||
"action": "menu_navigate",
|
||||
"level1": "설정",
|
||||
"level2": "알림설정",
|
||||
"expected": {
|
||||
"url_contains": "/settings/notification-settings",
|
||||
"visible": ["알림설정", "알림"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"알림 설정 폼 표시",
|
||||
"알림 ON/OFF 토글 존재",
|
||||
"저장 버튼 존재"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "알림 설정 폼 구조 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"이메일 알림 토글",
|
||||
"푸시 알림 토글",
|
||||
"결재 알림 설정",
|
||||
"근태 알림 설정"
|
||||
],
|
||||
"expected": "알림 설정 폼 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 현재 알림 설정 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"이메일 알림 상태 표시",
|
||||
"푸시 알림 상태 표시",
|
||||
"결재 알림 상태 표시"
|
||||
],
|
||||
"expected": "현재 알림 설정 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 이메일 알림 토글",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[name*='email'], label:has-text('이메일') input[type='checkbox']",
|
||||
"expected": {
|
||||
"toggle_changed": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 푸시 알림 토글",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[name*='push'], label:has-text('푸시') input[type='checkbox']",
|
||||
"expected": {
|
||||
"toggle_changed": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 결재 알림 설정",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[name*='approval'], label:has-text('결재') input[type='checkbox']",
|
||||
"expected": {
|
||||
"toggle_changed": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 필수 검증 #2: 알림 설정 저장",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('저장'), button:has-text('적용')",
|
||||
"verify": {
|
||||
"url_maintained": true,
|
||||
"no_error_page": true,
|
||||
"api_call": "PUT /api/v1/settings/notifications",
|
||||
"toast": "저장|적용|완료|성공"
|
||||
},
|
||||
"expected": "알림 설정 저장 완료"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 저장 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"변경된 알림 설정 반영"
|
||||
],
|
||||
"expected": "수정된 설정 반영"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "알림 유형별 설정 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"시스템 알림 설정",
|
||||
"업무 알림 설정",
|
||||
"일정 알림 설정"
|
||||
],
|
||||
"expected": "알림 유형별 설정 표시"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "알림 수신 시간 설정 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"수신 시간대 설정",
|
||||
"방해금지 시간 설정"
|
||||
],
|
||||
"expected": "시간 설정 표시"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "알림 테스트 전송 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"테스트 알림 전송 버튼"
|
||||
],
|
||||
"expected": "테스트 버튼 표시"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/settings/notifications",
|
||||
"description": "알림 설정 조회"
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"endpoint": "/api/v1/settings/notifications",
|
||||
"description": "알림 설정 수정"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"endpoint": "/api/v1/settings/notifications/test",
|
||||
"description": "테스트 알림 전송"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 2,
|
||||
"name": "저장 버튼",
|
||||
"steps": [8],
|
||||
"criteria": "API 호출 + 성공 토스트 + 설정 반영"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"criteria": "알림 설정 폼, 저장 버튼 존재"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"onUpdateFail": "페이지 새로고침으로 원래 값 복원",
|
||||
"note": "설정 페이지는 수정 후 원복 테스트 권장"
|
||||
}
|
||||
}
|
||||
158
_backup_before_enhance/settings-permission.json
Normal file
158
_backup_before_enhance/settings-permission.json
Normal file
@@ -0,0 +1,158 @@
|
||||
{
|
||||
"id": "settings-permission",
|
||||
"name": "권한관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "설정 > 권한관리 메뉴의 권한 그룹 목록 조회 및 UI 검증 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "설정",
|
||||
"level2": "권한관리",
|
||||
"expectedUrl": "/settings/permissions",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 설정 > 권한관리",
|
||||
"action": "menu_navigate",
|
||||
"level1": "설정",
|
||||
"level2": "권한관리",
|
||||
"expected": {
|
||||
"url_contains": "/settings/permissions",
|
||||
"visible": ["권한관리", "권한"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"권한 그룹 목록 표시",
|
||||
"권한 추가 버튼 존재",
|
||||
"권한 설정 영역 존재"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "권한 그룹 목록 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"권한 그룹 목록 테이블 또는 리스트",
|
||||
"기본 역할 (관리자, 사용자 등) 표시",
|
||||
"권한 추가 버튼"
|
||||
],
|
||||
"expected": "권한 목록 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 첫 번째 권한 그룹 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:first-child, li:first-child, [class*='list'] > *:first-child",
|
||||
"expected": {
|
||||
"visible": ["메뉴 권한", "기능 권한"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 권한 체크박스 구조 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"메뉴별 읽기/쓰기/삭제 권한",
|
||||
"전체 선택/해제 기능"
|
||||
],
|
||||
"expected": "권한 체크박스 매트릭스 표시"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 권한 상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"권한 그룹 정보 표시됨",
|
||||
"체크박스 또는 권한 목록 표시"
|
||||
],
|
||||
"expected": "권한 상세 정보 표시"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "권한 추가 버튼 확인",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('추가'), button:has-text('권한 추가'), button:has-text('역할 추가')",
|
||||
"expected": {
|
||||
"modal_or_form": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "추가 모달 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"역할명 입력 필드",
|
||||
"설명 입력 필드"
|
||||
],
|
||||
"expected": "권한 추가 폼 표시"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "추가 모달 닫기",
|
||||
"action": "close_modal_if_open",
|
||||
"expected": "모달 닫힘"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "저장 버튼 존재 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"저장 또는 적용 버튼 존재"
|
||||
],
|
||||
"expected": "저장 버튼 표시"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "삭제 버튼 존재 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"삭제 버튼 존재 여부"
|
||||
],
|
||||
"expected": "삭제 기능 확인"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "권한관리 페이지 최종 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"권한관리 페이지 정상 동작"
|
||||
],
|
||||
"expected": "페이지 정상 확인"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/roles",
|
||||
"description": "역할 목록 조회"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"criteria": "권한 목록, 추가 버튼, 권한 체크박스 존재"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"note": "READ-only 패턴으로 안정성 우선"
|
||||
}
|
||||
}
|
||||
153
_backup_before_enhance/settings-popup.json
Normal file
153
_backup_before_enhance/settings-popup.json
Normal file
@@ -0,0 +1,153 @@
|
||||
{
|
||||
"id": "settings-popup",
|
||||
"name": "팝업관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "설정 > 팝업관리 메뉴의 팝업 목록 조회 및 UI 검증 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "설정",
|
||||
"level2": "팝업관리",
|
||||
"expectedUrl": "/settings/popup-management",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 설정 > 팝업관리",
|
||||
"action": "menu_navigate",
|
||||
"level1": "설정",
|
||||
"level2": "팝업관리",
|
||||
"expected": {
|
||||
"url_contains": "/settings/popup",
|
||||
"visible": ["팝업관리", "팝업"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"팝업 목록 표시",
|
||||
"팝업 등록 버튼 존재",
|
||||
"상태 필터 존재"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "팝업 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
"팝업 제목 컬럼",
|
||||
"상태 컬럼",
|
||||
"기간 컬럼",
|
||||
"노출 위치 컬럼"
|
||||
],
|
||||
"expected": "팝업 테이블 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "기존 팝업 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"등록된 팝업 존재 또는 등록된 팝업 없음"
|
||||
],
|
||||
"expected": "팝업 목록 상태 확인"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "팝업 등록 버튼 확인",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('등록'), button:has-text('추가'), button:has-text('신규')",
|
||||
"expected": {
|
||||
"modal_open": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "등록 폼 요소 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"제목 입력 필드",
|
||||
"내용 입력 필드",
|
||||
"기간 설정 필드"
|
||||
],
|
||||
"expected": "팝업 등록 폼 표시"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "등록 모달 닫기",
|
||||
"action": "close_modal_if_open",
|
||||
"expected": "모달 닫힘"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 팝업 목록 데이터 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"팝업 목록 데이터 표시됨"
|
||||
],
|
||||
"expected": "팝업 목록 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 첫 번째 행 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:first-child"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 팝업 상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"팝업 상세 정보 표시"
|
||||
],
|
||||
"expected": "팝업 상세 정보 확인"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "상세 모달 닫기",
|
||||
"action": "close_modal_if_open",
|
||||
"expected": "모달 닫힘"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "팝업관리 페이지 최종 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"팝업 목록 구조 정상",
|
||||
"등록 버튼 존재"
|
||||
],
|
||||
"expected": "팝업관리 페이지 정상"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/settings/popups",
|
||||
"description": "팝업 목록 조회"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"criteria": "팝업 목록, 등록 버튼, 상태 필터 존재"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"note": "READ-only 패턴으로 안정성 우선"
|
||||
}
|
||||
}
|
||||
71
_backup_before_enhance/settings-position.json
Normal file
71
_backup_before_enhance/settings-position.json
Normal file
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"id": "settings-position",
|
||||
"name": "직책관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "설정 > 직책관리 목록/검색/상세 기능 검증",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "설정",
|
||||
"level2": "직책관리",
|
||||
"expectedUrl": "/settings/titles",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 설정 > 직책관리",
|
||||
"action": "menu_navigate",
|
||||
"level1": "설정",
|
||||
"level2": "직책관리",
|
||||
"expected": { "url_contains": "/settings" }
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "목업 감지",
|
||||
"action": "verify_not_mockup"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "직책관리 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:직책"]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "설정 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:설정"]
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "추가 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('추가'), button:has-text('등록'), button:has-text('신규')"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "대기",
|
||||
"action": "wait",
|
||||
"duration": 1000
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "모달 닫기",
|
||||
"action": "close_modal_if_open"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "직책관리 최종 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:직책"]
|
||||
}
|
||||
]
|
||||
}
|
||||
71
_backup_before_enhance/settings-rank.json
Normal file
71
_backup_before_enhance/settings-rank.json
Normal file
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"id": "settings-rank",
|
||||
"name": "직급관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "설정 > 직급관리 목록/검색/상세 기능 검증",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "설정",
|
||||
"level2": "직급관리",
|
||||
"expectedUrl": "/settings/ranks",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 설정 > 직급관리",
|
||||
"action": "menu_navigate",
|
||||
"level1": "설정",
|
||||
"level2": "직급관리",
|
||||
"expected": { "url_contains": "/settings" }
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "목업 감지",
|
||||
"action": "verify_not_mockup"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "직급관리 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:직급"]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "설정 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:설정"]
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "추가 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('추가'), button:has-text('등록'), button:has-text('신규')"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "대기",
|
||||
"action": "wait",
|
||||
"duration": 1000
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "모달 닫기",
|
||||
"action": "close_modal_if_open"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "직급관리 최종 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:직급"]
|
||||
}
|
||||
]
|
||||
}
|
||||
134
_backup_before_enhance/settings-subscription.json
Normal file
134
_backup_before_enhance/settings-subscription.json
Normal file
@@ -0,0 +1,134 @@
|
||||
{
|
||||
"id": "settings-subscription",
|
||||
"name": "구독관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "설정 > 구독관리 메뉴의 구독 정보 조회/플랜 비교 기능 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "설정",
|
||||
"level2": "구독관리",
|
||||
"expectedUrl": "/subscription",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"selectors": {
|
||||
"planCard": ".card, [class*='plan'], [class*='Plan'], [class*='subscription']",
|
||||
"priceText": "[class*='price'], [class*='Price'], [class*='amount'], [class*='cost']",
|
||||
"dateInfo": "[class*='date'], [class*='period'], time",
|
||||
"paymentInfo": "[class*='payment'], [class*='billing'], [class*='card']",
|
||||
"planTable": "table, [class*='plan-compare'], [class*='pricing-table']",
|
||||
"actionButton": "button, [role='button']",
|
||||
"usageCard": "[class*='usage'], [class*='quota'], [class*='limit']",
|
||||
"historyTable": "table tbody tr, [class*='history'] li, [class*='payment-list']"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 설정 > 구독관리",
|
||||
"action": "menu_navigate",
|
||||
"level1": "설정",
|
||||
"level2": "구독관리",
|
||||
"expected": {
|
||||
"url_contains": "/subscription",
|
||||
"visible": ["구독관리", "구독"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"구독 정보 표시",
|
||||
"플랜 정보 표시",
|
||||
"결제 정보 표시"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "현재 플랜 카드 존재 확인",
|
||||
"action": "verify_element",
|
||||
"target": "planCard",
|
||||
"verification": { "exists": true }
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "플랜/가격 정보 텍스트 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => { const text = document.body.innerText; return text.includes('플랜') || text.includes('요금') || text.includes('Plan') || text.includes('구독'); })()"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "구독 기간/날짜 정보 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => { const text = document.body.innerText; return text.includes('기간') || text.includes('시작') || text.includes('종료') || /\\d{4}[-./]\\d{2}[-./]\\d{2}/.test(text); })()"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "결제 관련 정보 표시 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => { const text = document.body.innerText; return text.includes('결제') || text.includes('카드') || text.includes('금액') || text.includes('원'); })()"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "플랜 비교/변경 UI 확인",
|
||||
"action": "verify_element",
|
||||
"target": "table, [class*='plan'], [class*='compare'], button:has-text('플랜'), button:has-text('변경'), button:has-text('업그레이드')"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "사용량 현황 영역 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => { const text = document.body.innerText; return text.includes('사용') || text.includes('용량') || text.includes('사용자') || text.includes('%'); })()"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "결제 내역 영역 확인",
|
||||
"action": "verify_element",
|
||||
"target": "table tbody tr, [class*='history'], [class*='payment-list'], [class*='billing-history']"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "다운로드/영수증 버튼 확인",
|
||||
"action": "verify_element",
|
||||
"target": "button:has-text('다운로드'), button:has-text('영수증'), button:has-text('Download'), a:has-text('영수증'), [class*='download']"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "결제 수단 관련 UI 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => { const text = document.body.innerText; return text.includes('결제 수단') || text.includes('카드') || text.includes('계좌') || document.querySelector('[class*=\"payment-method\"], [class*=\"card-info\"]'); })()"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "구독 관리 버튼 확인 (취소/해지 포함)",
|
||||
"action": "verify_element",
|
||||
"target": "button:has-text('취소'), button:has-text('해지'), button:has-text('관리'), button:has-text('변경'), [class*='cancel'], [class*='manage']"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/subscription",
|
||||
"description": "구독 정보 조회"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"criteria": "구독 정보, 플랜 정보, 결제 정보 존재"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"note": "조회 전용 페이지로 데이터 변경 없음 (결제/플랜 변경은 별도 테스트)"
|
||||
}
|
||||
}
|
||||
197
_backup_before_enhance/settings-vacation-policy.json
Normal file
197
_backup_before_enhance/settings-vacation-policy.json
Normal file
@@ -0,0 +1,197 @@
|
||||
{
|
||||
"id": "settings-vacation-policy",
|
||||
"name": "휴가정책 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "설정 > 휴가정책 메뉴의 휴가 정책 조회/수정/저장 기능 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "설정",
|
||||
"level2": "휴가정책",
|
||||
"expectedUrl": "/settings/leave-policy",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"testData": {
|
||||
"update": {
|
||||
"annualLeave": "15",
|
||||
"halfDayEnabled": true,
|
||||
"carryOverDays": "5",
|
||||
"memo": "E2E 테스트 휴가정책"
|
||||
},
|
||||
"restore": {
|
||||
"annualLeave": "15",
|
||||
"halfDayEnabled": true,
|
||||
"carryOverDays": "5"
|
||||
}
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 설정 > 휴가정책",
|
||||
"action": "menu_navigate",
|
||||
"level1": "설정",
|
||||
"level2": "휴가정책",
|
||||
"expected": {
|
||||
"url_contains": "/settings/leave-policy",
|
||||
"visible": ["휴가정책", "휴가"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"휴가 정책 설정 폼 표시",
|
||||
"연차 부여 기준 설정 가능",
|
||||
"저장 버튼 존재"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "휴가 정책 폼 구조 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"연차 부여 기준 입력",
|
||||
"반차 사용 여부 설정",
|
||||
"휴가 이월 일수 설정",
|
||||
"휴가 유형별 설정"
|
||||
],
|
||||
"expected": "휴가 정책 폼 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 현재 정책 값 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"연차 부여 기준 표시",
|
||||
"반차 사용 설정 표시",
|
||||
"이월 일수 표시"
|
||||
],
|
||||
"expected": "현재 정책 값 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 연차 부여 기준 수정",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[name*='annual'], input[placeholder*='연차']"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 반차 사용 설정",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[type='checkbox'][name*='half'], label:has-text('반차')",
|
||||
"expected": {
|
||||
"checkbox_toggled": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 이월 일수 수정",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[name*='carryOver'], input[placeholder*='이월']"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 필수 검증 #2: 정책 저장",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('저장'), button:has-text('적용')",
|
||||
"verify": {
|
||||
"url_maintained": true,
|
||||
"no_error_page": true,
|
||||
"api_call": "PUT /api/v1/settings/vacation-policy",
|
||||
"toast": "저장|적용|완료|성공"
|
||||
},
|
||||
"expected": "휴가 정책 저장 완료"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 저장 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"연차: 15",
|
||||
"이월 일수: 5"
|
||||
],
|
||||
"expected": "수정된 정책 반영"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "휴가 유형 관리 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"연차 유형 표시",
|
||||
"병가 유형 표시",
|
||||
"경조사 유형 표시"
|
||||
],
|
||||
"expected": "휴가 유형 목록 표시"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 휴가 유형 추가 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"휴가 유형 추가 버튼 존재"
|
||||
],
|
||||
"expected": "추가 버튼 표시"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "정책 적용 대상 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"부서별 적용 설정",
|
||||
"직급별 적용 설정"
|
||||
],
|
||||
"expected": "적용 대상 설정 표시"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/settings/vacation-policy",
|
||||
"description": "휴가 정책 조회"
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"endpoint": "/api/v1/settings/vacation-policy",
|
||||
"description": "휴가 정책 수정"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/vacation-types",
|
||||
"description": "휴가 유형 목록 조회"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 2,
|
||||
"name": "저장 버튼",
|
||||
"steps": [8],
|
||||
"criteria": "API 호출 + 성공 토스트 + 설정 반영"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"criteria": "휴가 정책 폼, 저장 버튼 존재"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"onUpdateFail": "페이지 새로고침으로 원래 값 복원",
|
||||
"note": "설정 페이지는 수정 후 원복 테스트 권장"
|
||||
}
|
||||
}
|
||||
188
_backup_before_enhance/settings-work-schedule.json
Normal file
188
_backup_before_enhance/settings-work-schedule.json
Normal file
@@ -0,0 +1,188 @@
|
||||
{
|
||||
"id": "settings-work-schedule",
|
||||
"name": "근무일정 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "설정 > 근무일정 메뉴의 근무일정 조회/수정/저장 기능 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "설정",
|
||||
"level2": "근무일정",
|
||||
"expectedUrl": "/settings/work-schedule",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"testData": {
|
||||
"update": {
|
||||
"workDays": "월,화,수,목,금",
|
||||
"startTime": "09:00",
|
||||
"endTime": "18:00",
|
||||
"breakTime": "60"
|
||||
}
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 설정 > 근무일정",
|
||||
"action": "menu_navigate",
|
||||
"level1": "설정",
|
||||
"level2": "근무일정",
|
||||
"expected": {
|
||||
"url_contains": "/settings/work-schedule",
|
||||
"visible": ["근무일정", "근무"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"근무일정 설정 폼 표시",
|
||||
"근무일 선택 가능",
|
||||
"저장 버튼 존재"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "근무일정 폼 구조 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"근무일 선택 (월~일)",
|
||||
"출근 시간 입력",
|
||||
"퇴근 시간 입력",
|
||||
"휴게 시간 설정"
|
||||
],
|
||||
"expected": "근무일정 폼 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 현재 근무일정 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"근무일 표시",
|
||||
"출근 시간 표시",
|
||||
"퇴근 시간 표시"
|
||||
],
|
||||
"expected": "현재 근무일정 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 출근 시간 수정",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[name*='start'], input[type='time']:first-of-type"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 퇴근 시간 수정",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[name*='end'], input[type='time']:last-of-type"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 휴게 시간 설정",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[name*='break'], input[placeholder*='휴게']"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 필수 검증 #2: 근무일정 저장",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('저장'), button:has-text('적용')",
|
||||
"verify": {
|
||||
"url_maintained": true,
|
||||
"no_error_page": true,
|
||||
"api_call": "PUT /api/v1/settings/work-schedule",
|
||||
"toast": "저장|적용|완료|성공"
|
||||
},
|
||||
"expected": "근무일정 저장 완료"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 저장 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"출근: 09:00",
|
||||
"퇴근: 18:00",
|
||||
"휴게: 60분"
|
||||
],
|
||||
"expected": "수정된 일정 반영"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "휴무일 설정 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"토요일 휴무 설정",
|
||||
"일요일 휴무 설정",
|
||||
"공휴일 자동 적용"
|
||||
],
|
||||
"expected": "휴무일 설정 표시"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "주간 근무시간 계산 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"주간 근무시간 합계 표시"
|
||||
],
|
||||
"expected": "근무시간 자동 계산"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "부서별 근무일정 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"부서별 일정 설정 가능"
|
||||
],
|
||||
"expected": "부서별 일정 표시"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/settings/work-schedule",
|
||||
"description": "근무일정 조회"
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"endpoint": "/api/v1/settings/work-schedule",
|
||||
"description": "근무일정 수정"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/holidays",
|
||||
"description": "공휴일 목록 조회"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 2,
|
||||
"name": "저장 버튼",
|
||||
"steps": [8],
|
||||
"criteria": "API 호출 + 성공 토스트 + 설정 반영"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"criteria": "근무일정 폼, 저장 버튼 존재"
|
||||
}
|
||||
],
|
||||
"rollbackPlan": {
|
||||
"onUpdateFail": "페이지 새로고침으로 원래 값 복원",
|
||||
"note": "설정 페이지는 수정 후 원복 테스트 권장"
|
||||
}
|
||||
}
|
||||
83
_backup_before_enhance/shipment-management.json
Normal file
83
_backup_before_enhance/shipment-management.json
Normal file
@@ -0,0 +1,83 @@
|
||||
{
|
||||
"id": "shipment-management",
|
||||
"name": "출고관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "출고관리 > 출고관리 목록/상세 기능 검증",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"menuNavigation": {
|
||||
"level1": "출고관리",
|
||||
"level2": "출고관리",
|
||||
"expectedUrl": "/outbound/shipments",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "메뉴 진입: 출고관리 > 출고관리",
|
||||
"action": "menu_navigate",
|
||||
"level1": "출고관리",
|
||||
"level2": "출고관리",
|
||||
"expected": { "url_contains": "/outbound" }
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "목업 감지",
|
||||
"action": "verify_not_mockup"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "출고관리 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:출고"]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "UI 요소 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:관리"]
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "검색 입력 시도",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[type='search'], input[placeholder*='검색'], input[placeholder*='조회'], [class*='search'] input"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "대기",
|
||||
"action": "wait",
|
||||
"duration": 1000
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "행 클릭 시도",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr, [role='row']:not(:first-child), [class*='list'] [class*='item']"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "상세 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:출고"]
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "모달 닫기",
|
||||
"action": "close_modal_if_open"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "최종 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:출고"]
|
||||
}
|
||||
]
|
||||
}
|
||||
725
_backup_before_enhance/vendor-ledger.json
Normal file
725
_backup_before_enhance/vendor-ledger.json
Normal file
@@ -0,0 +1,725 @@
|
||||
{
|
||||
"enabled": true,
|
||||
"id": "vendor-ledger",
|
||||
"name": "거래처원장 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"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": [
|
||||
"거래처원장",
|
||||
"거래처 원장",
|
||||
"회계관리"
|
||||
]
|
||||
},
|
||||
"menuNavigation": {
|
||||
"level1": "회계관리",
|
||||
"level2": "거래처원장",
|
||||
"expectedUrl": "/ko/accounting/vendor-ledger",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"menuNavigationEnhanced": {
|
||||
"strategy": "scroll-and-search",
|
||||
"level1": {
|
||||
"text": "회계관리",
|
||||
"alternativeNames": [
|
||||
"회계",
|
||||
"Accounting"
|
||||
],
|
||||
"scrollConfig": {
|
||||
"direction": "down",
|
||||
"maxScrollAttempts": 5,
|
||||
"scrollAmount": 200
|
||||
}
|
||||
},
|
||||
"level2": {
|
||||
"text": "거래처원장",
|
||||
"alternativeNames": [
|
||||
"거래처 원장",
|
||||
"Vendor Ledger"
|
||||
],
|
||||
"scrollConfig": {
|
||||
"direction": "down",
|
||||
"maxScrollAttempts": 3,
|
||||
"scrollAmount": 150
|
||||
}
|
||||
},
|
||||
"expectedUrl": "/ko/accounting/vendor-ledger",
|
||||
"fallbackUrl": "/ko/accounting/vendor-ledger"
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": "사이드바 메뉴 전체 펼치기",
|
||||
"description": "모두 펼치기 버튼을 클릭하여 전체 메뉴를 펼친 후 메뉴 탐색 준비",
|
||||
"actions": [
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "document.querySelector('.sidebar-scroll')?.scrollTo({top:0,behavior:'instant'})"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 300
|
||||
},
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "Array.from(document.querySelectorAll('button')).find(b => b.innerText?.includes('모두 펼치기'))?.click()"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 2000
|
||||
}
|
||||
],
|
||||
"expected": "사이드바 전체 메뉴가 펼쳐짐"
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"name": "로그인 상태 확인",
|
||||
"action": "verify_page",
|
||||
"expected": "이미 로그인된 상태"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "2단계 메뉴 진입: 회계관리 > 거래처원장",
|
||||
"description": "회계관리 > 거래처원장 메뉴로 이동하여 페이지 로드 확인 (scrollAndFind 패턴 사용)",
|
||||
"actions": [
|
||||
{
|
||||
"type": "scrollAndFind",
|
||||
"level": 1,
|
||||
"target": "회계관리",
|
||||
"alternativeSelectors": [
|
||||
"text=회계관리",
|
||||
"[data-menu='accounting']",
|
||||
"a:has-text('회계관리')",
|
||||
"span:has-text('회계관리')"
|
||||
],
|
||||
"scrollConfig": {
|
||||
"container": ".sidebar-scroll, [class*='sidebar'], nav",
|
||||
"direction": "down",
|
||||
"maxAttempts": 5,
|
||||
"scrollAmount": 200
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "회계관리"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 500
|
||||
},
|
||||
{
|
||||
"type": "scrollAndFind",
|
||||
"level": 2,
|
||||
"target": "거래처원장",
|
||||
"alternativeSelectors": [
|
||||
"text=거래처원장",
|
||||
"[data-menu='vendor-ledger']",
|
||||
"a:has-text('거래처원장')",
|
||||
"span:has-text('거래처원장')"
|
||||
],
|
||||
"scrollConfig": {
|
||||
"container": ".sidebar-scroll, [class*='sidebar'], nav",
|
||||
"direction": "down",
|
||||
"maxAttempts": 3,
|
||||
"scrollAmount": 150
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "거래처원장"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"target": "페이지 로드 완료"
|
||||
}
|
||||
],
|
||||
"expected": {
|
||||
"url": "/ko/accounting/vendor-ledger",
|
||||
"pageTitle": "거래처원장",
|
||||
"elements": [
|
||||
"통계 카드",
|
||||
"테이블"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"입력 필드 존재 (검색창, 날짜 선택)",
|
||||
"동작하는 버튼 존재 (엑셀 다운로드)",
|
||||
"테이블 데이터 표시",
|
||||
"API 호출 확인"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"전기 이월 카드 표시",
|
||||
"매출 카드 표시",
|
||||
"수금 카드 표시",
|
||||
"잔액 카드 표시"
|
||||
],
|
||||
"expected": "4개 통계 카드 모두 표시, 금액 형식 확인"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
"체크박스 컬럼",
|
||||
"No. 컬럼",
|
||||
"거래처명 컬럼",
|
||||
"이월잔액 컬럼",
|
||||
"매출 컬럼",
|
||||
"수금 컬럼",
|
||||
"잔액 컬럼",
|
||||
"결제일 컬럼"
|
||||
],
|
||||
"expected": "8개 컬럼 존재, 합계 행 표시"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "기간 설정 - 시작일 변경",
|
||||
"action": "click_if_exists",
|
||||
"target": "startDate",
|
||||
"value": "2025-01-01",
|
||||
"expected": "시작일 변경 후 데이터 재조회"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "기간 설정 - 종료일 변경",
|
||||
"action": "click_if_exists",
|
||||
"target": "endDate",
|
||||
"value": "2025-12-31",
|
||||
"expected": "종료일 변경 후 데이터 재조회"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "기간 설정 - 데이터 변화 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"테이블 데이터 갱신",
|
||||
"통계 카드 값 갱신",
|
||||
"합계 행 값 갱신"
|
||||
],
|
||||
"expected": "기간에 맞는 데이터로 변경됨"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "⚠️ 필수 검증: 검색 기능 테스트",
|
||||
"actions": [
|
||||
{
|
||||
"type": "capture",
|
||||
"variable": "beforeSearchCount",
|
||||
"selector": "table tbody tr",
|
||||
"extract": "count",
|
||||
"description": "검색 전 행 수 저장"
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "input[type='search'], input[placeholder*='검색']",
|
||||
"description": "검색 입력창 존재 확인"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 1000,
|
||||
"description": "검색 결과 로딩 대기"
|
||||
},
|
||||
{
|
||||
"type": "capture",
|
||||
"variable": "afterSearchCount",
|
||||
"selector": "table tbody tr",
|
||||
"extract": "count",
|
||||
"description": "검색 후 행 수 저장"
|
||||
}
|
||||
],
|
||||
"verify": {
|
||||
"searchApplied": true,
|
||||
"tableContains": "{testData.searchKeyword}",
|
||||
"dataChanged": "beforeSearchCount may differ from afterSearchCount"
|
||||
},
|
||||
"expected": "검색어에 맞는 거래처만 필터링"
|
||||
},
|
||||
{
|
||||
"id": "9-1",
|
||||
"name": "검색 결과 데이터 검증",
|
||||
"description": "검색 결과의 모든 행이 검색어를 포함하는지 확인",
|
||||
"verify": {
|
||||
"allRowsContain": "{testData.searchKeyword}",
|
||||
"columnToCheck": "거래처명"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "검색 결과 확인",
|
||||
"action": "verify_search_result",
|
||||
"checks": [
|
||||
"테이블 행 수 변화",
|
||||
"검색어 포함 거래처명 표시"
|
||||
],
|
||||
"expected": "검색 결과 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "검색 초기화",
|
||||
"actions": [
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "input[type='search'], input[placeholder*='검색']",
|
||||
"description": "검색 입력창 존재 확인"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 500
|
||||
},
|
||||
{
|
||||
"type": "capture",
|
||||
"variable": "afterClearCount",
|
||||
"selector": "table tbody tr",
|
||||
"extract": "count"
|
||||
}
|
||||
],
|
||||
"verify": {
|
||||
"dataRestored": "afterClearCount should equal beforeSearchCount"
|
||||
},
|
||||
"expected": "전체 데이터 다시 표시"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "체크박스 선택",
|
||||
"action": "click_if_exists",
|
||||
"target": "first_row",
|
||||
"expected": "첫 번째 행 체크박스 선택됨"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"name": "전체 선택 체크박스",
|
||||
"action": "click_if_exists",
|
||||
"target": "select_all",
|
||||
"expected": "모든 행 체크박스 선택됨"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"name": "전체 선택 해제",
|
||||
"action": "click_if_exists",
|
||||
"target": "select_all",
|
||||
"expected": "모든 행 체크박스 해제됨"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"name": "필수 검증 #1: 엑셀 다운로드",
|
||||
"action": "click_download",
|
||||
"target": "엑셀 다운로드",
|
||||
"checks": [
|
||||
"버튼 클릭",
|
||||
"Network API 호출 확인 (/api/v1/vendor-ledger/export)",
|
||||
"Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
"파일 다운로드 이벤트 발생",
|
||||
"성공 토스트 메시지 (엑셀 파일이 다운로드되었습니다)"
|
||||
],
|
||||
"expected": "엑셀 파일 다운로드 완료"
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"name": "테이블 행 클릭 - 상세 페이지 이동",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:first-child",
|
||||
"expected": "거래처원장 상세 페이지로 이동"
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"name": "상세 페이지 - URL 파라미터 확인",
|
||||
"action": "verify_url",
|
||||
"checks": [
|
||||
"URL에 거래처 ID 포함",
|
||||
"start_date 파라미터 포함",
|
||||
"end_date 파라미터 포함"
|
||||
],
|
||||
"expected": "URL 파라미터 정상 전달"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"name": "상세 페이지 - 헤더 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"거래처원장 상세 (거래명세서별) 타이틀",
|
||||
"목록 버튼 존재"
|
||||
],
|
||||
"expected": "상세 페이지 헤더 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"name": "상세 페이지 - 거래처 정보 카드 확인",
|
||||
"action": "verify_vendor_info",
|
||||
"checks": [
|
||||
"회사명 표시",
|
||||
"사업자등록번호 표시",
|
||||
"대표자 표시",
|
||||
"전화번호 표시",
|
||||
"모바일 표시",
|
||||
"팩스 표시",
|
||||
"이메일 표시",
|
||||
"주소 표시",
|
||||
"기간 표시"
|
||||
],
|
||||
"expected": "거래처 정보 모두 표시"
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"name": "상세 페이지 - 요약 통계 확인",
|
||||
"action": "verify_summary",
|
||||
"checks": [
|
||||
"이월잔액 표시",
|
||||
"매출 표시 (녹색)",
|
||||
"수금 표시 (파란색)",
|
||||
"잔액 표시"
|
||||
],
|
||||
"expected": "4개 요약 통계 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"name": "상세 페이지 - 판매/수금 내역 테이블 확인",
|
||||
"action": "verify_transaction_table",
|
||||
"checks": [
|
||||
"일자 컬럼",
|
||||
"적요 컬럼",
|
||||
"판매 컬럼",
|
||||
"수금 컬럼",
|
||||
"잔액 컬럼",
|
||||
"작업 컬럼"
|
||||
],
|
||||
"expected": "판매/수금 내역 테이블 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"name": "상세 페이지 - 기간 변경",
|
||||
"action": "click_if_exists",
|
||||
"startDate": "2025-06-01",
|
||||
"endDate": "2025-06-30",
|
||||
"expected": "기간 변경 후 거래 내역 재조회",
|
||||
"target": "input[type='date'], [class*='date-picker']"
|
||||
},
|
||||
{
|
||||
"id": 23,
|
||||
"name": "상세 페이지 - 거래 내역 데이터 변화 확인",
|
||||
"action": "verify_transactions_update",
|
||||
"checks": [
|
||||
"테이블 데이터 갱신",
|
||||
"요약 통계 값 갱신"
|
||||
],
|
||||
"expected": "변경된 기간의 데이터 표시"
|
||||
},
|
||||
{
|
||||
"id": 24,
|
||||
"name": "⚠️ 필수 검증: PDF 다운로드 전 페이지 스크린샷",
|
||||
"description": "PDF 생성 전 페이지 상태를 스크린샷으로 캡처하여 CSS 문제 감지용 기준 이미지 확보",
|
||||
"actions": [
|
||||
{
|
||||
"type": "screenshot",
|
||||
"name": "pdf-preview-before-download",
|
||||
"fullPage": true,
|
||||
"savePath": "tests/e2e/results/hotfix/screenshots/",
|
||||
"description": "PDF 생성 대상 페이지 전체 캡처"
|
||||
},
|
||||
{
|
||||
"type": "screenshot",
|
||||
"name": "pdf-content-area",
|
||||
"selector": ".vendor-ledger-detail, .pdf-content, main",
|
||||
"savePath": "tests/e2e/results/hotfix/screenshots/",
|
||||
"description": "PDF 콘텐츠 영역만 캡처"
|
||||
}
|
||||
],
|
||||
"verify": {
|
||||
"screenshotCaptured": true,
|
||||
"purpose": "PDF CSS 문제 감지를 위한 기준 이미지"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "24-1",
|
||||
"name": "⚠️ 필수 검증: PDF 다운로드 실행 및 파일 보관",
|
||||
"description": "PDF 다운로드 후 파일을 지정 폴더에 보관하여 수동 검증 가능하게 함",
|
||||
"actions": [
|
||||
{
|
||||
"type": "expectResponse",
|
||||
"id": "pdf-download-response",
|
||||
"urlPattern": "/api/v1/vendor-ledger/*/export-pdf",
|
||||
"description": "PDF 다운로드 API 응답 대기 설정"
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "PDF 다운로드",
|
||||
"description": "PDF 다운로드 버튼 클릭"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 3000,
|
||||
"description": "PDF 생성 및 다운로드 대기"
|
||||
},
|
||||
{
|
||||
"type": "assertResponse",
|
||||
"id": "pdf-download-response",
|
||||
"checks": {
|
||||
"status": 200,
|
||||
"contentType": "application/pdf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "saveDownloadedFile",
|
||||
"targetPath": "tests/e2e/results/hotfix/pdf-samples/",
|
||||
"fileNamePattern": "vendor-ledger-{vendorId}-{timestamp}.pdf",
|
||||
"description": "다운로드된 PDF 파일을 지정 폴더에 보관"
|
||||
}
|
||||
],
|
||||
"verify": {
|
||||
"apiSuccess": true,
|
||||
"fileDownloaded": true,
|
||||
"fileSaved": "tests/e2e/results/hotfix/pdf-samples/"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "24-2",
|
||||
"name": "⚠️ PDF 파일 유효성 검증",
|
||||
"description": "다운로드된 PDF 파일의 기본 유효성 검사",
|
||||
"actions": [
|
||||
{
|
||||
"type": "verifyDownloadedFile",
|
||||
"checks": {
|
||||
"fileExists": true,
|
||||
"fileSize": "> 1024",
|
||||
"pdfSignature": "%PDF-",
|
||||
"description": "PDF 파일 헤더 검증"
|
||||
}
|
||||
}
|
||||
],
|
||||
"verify": {
|
||||
"pdfValid": true,
|
||||
"minFileSize": "1KB 이상"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "24-3",
|
||||
"name": "📋 PDF 스타일 수동 확인 체크리스트",
|
||||
"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": "인쇄 호환성"
|
||||
}
|
||||
],
|
||||
"outputFiles": {
|
||||
"screenshot": "tests/e2e/results/hotfix/screenshots/pdf-preview-before-download-*.png",
|
||||
"pdfFile": "tests/e2e/results/hotfix/pdf-samples/vendor-ledger-*.pdf"
|
||||
},
|
||||
"reportFlag": {
|
||||
"requiresManualReview": true,
|
||||
"message": "⚠️ PDF 스타일 수동 확인 필요 - 위 체크리스트 항목을 PDF 파일에서 직접 확인하세요"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 25,
|
||||
"name": "상세 페이지 - 작업 버튼 확인 (어음 항목)",
|
||||
"action": "verify_action_buttons",
|
||||
"checks": [
|
||||
"어음 관련 항목에 수정 버튼(Pencil 아이콘) 존재",
|
||||
"일반 항목에는 작업 버튼 없음"
|
||||
],
|
||||
"expected": "hasAction=true인 항목에만 버튼 표시"
|
||||
},
|
||||
{
|
||||
"id": 26,
|
||||
"name": "상세 페이지 - 목록 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "목록",
|
||||
"expected": "거래처원장 목록 페이지로 복귀"
|
||||
},
|
||||
{
|
||||
"id": 27,
|
||||
"name": "목록 페이지 복귀 확인",
|
||||
"action": "verify_url",
|
||||
"target": "/ko/accounting/vendor-ledger",
|
||||
"expected": "목록 페이지 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 28,
|
||||
"name": "페이지네이션 동작 확인",
|
||||
"action": "verify_pagination",
|
||||
"checks": [
|
||||
"현재 페이지 표시",
|
||||
"전체 페이지 수 표시",
|
||||
"페이지 이동 버튼 동작"
|
||||
],
|
||||
"expected": "페이지네이션 정상 동작"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "파일 다운로드 (엑셀/PDF)",
|
||||
"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"
|
||||
],
|
||||
"criteria": "스크린샷 캡처 + PDF 파일 보관 + 수동 체크리스트 확인",
|
||||
"manualReviewRequired": true,
|
||||
"outputPaths": {
|
||||
"screenshots": "tests/e2e/results/hotfix/screenshots/",
|
||||
"pdfFiles": "tests/e2e/results/hotfix/pdf-samples/"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "등록/저장 버튼",
|
||||
"steps": [],
|
||||
"criteria": "해당 없음 (조회 전용 페이지)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "검색/필터",
|
||||
"steps": [
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11
|
||||
],
|
||||
"criteria": "기간 설정 및 검색 시 데이터 변화 확인"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "모달 등록 완료",
|
||||
"steps": [],
|
||||
"criteria": "해당 없음 (조회 전용 페이지)"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [
|
||||
3
|
||||
],
|
||||
"criteria": "입력 필드, 동작 버튼, API 호출 확인"
|
||||
}
|
||||
],
|
||||
"testData": {
|
||||
"searchKeyword": "테스트",
|
||||
"dateRange": {
|
||||
"start": "2025-01-01",
|
||||
"end": "2025-12-31"
|
||||
},
|
||||
"detailDateRange": {
|
||||
"start": "2025-06-01",
|
||||
"end": "2025-06-30"
|
||||
}
|
||||
},
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/vendor-ledger",
|
||||
"description": "거래처원장 목록 조회"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/vendor-ledger/summary",
|
||||
"description": "거래처원장 요약 통계 조회"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/vendor-ledger/{id}",
|
||||
"description": "거래처원장 상세 조회"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/vendor-ledger/export",
|
||||
"description": "거래처원장 엑셀 다운로드"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/vendor-ledger/{id}/export-pdf",
|
||||
"description": "거래처원장 상세 PDF 다운로드"
|
||||
}
|
||||
]
|
||||
}
|
||||
576
_backup_before_enhance/vendor-management.json
Normal file
576
_backup_before_enhance/vendor-management.json
Normal file
@@ -0,0 +1,576 @@
|
||||
{
|
||||
"id": "vendor-management",
|
||||
"name": "거래처관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "회계관리 > 거래처관리 메뉴의 목록 조회, 필터, 검색, 상세 페이지 진입, 수정 및 저장 기능 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"navigation": {
|
||||
"targetUrl": "/accounting/vendors",
|
||||
"urlPattern": "/accounting/vendors",
|
||||
"menuHints": ["거래처관리", "거래처 관리", "회계관리"]
|
||||
},
|
||||
"menuNavigation": {
|
||||
"level1": "회계관리",
|
||||
"level2": "거래처관리",
|
||||
"expectedUrl": "/accounting/vendors",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"menuNavigationEnhanced": {
|
||||
"strategy": "scroll-and-search",
|
||||
"description": "사이드바를 스크롤하며 메뉴를 찾고 클릭하여 404를 방지",
|
||||
"level1": "회계관리",
|
||||
"level2": "거래처관리",
|
||||
"alternativeLevel1Names": ["회계관리", "회계 관리", "Accounting"],
|
||||
"alternativeLevel2Names": ["거래처관리", "거래처 관리", "Vendors"],
|
||||
"scrollConfig": {
|
||||
"sidebarSelector": "nav, aside, [role='navigation'], .sidebar, #sidebar",
|
||||
"menuItemSelector": "a, button, [role='menuitem'], [role='treeitem']",
|
||||
"scrollStep": 200,
|
||||
"maxScrollAttempts": 10,
|
||||
"scrollDelay": 300
|
||||
}
|
||||
},
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
"notes": {
|
||||
"skip": ["등록 버튼 (추후 구현 예정)", "삭제 기능 (보류)"],
|
||||
"focus": ["테이블 행 클릭 → 상세 페이지", "수정 모드 진입", "수정 후 저장"],
|
||||
"uiNotes": [
|
||||
"필터 드롭다운: Radix UI Select (button[role='combobox'])",
|
||||
"체크박스: Radix UI Checkbox (button[role='checkbox'])",
|
||||
"저장: 확인 다이얼로그 없이 직접 저장 후 목록으로 리다이렉트"
|
||||
]
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": "step-0",
|
||||
"name": "사이드바 메뉴 전체 펼치기",
|
||||
"description": "모두 펼치기 버튼을 클릭하여 전체 메뉴를 펼친 후 메뉴 탐색 준비",
|
||||
"actions": [
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "document.querySelector('.sidebar-scroll')?.scrollTo({top:0,behavior:'instant'})"
|
||||
},
|
||||
{ "type": "wait", "duration": 300 },
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "Array.from(document.querySelectorAll('button')).find(b => b.innerText?.includes('모두 펼치기'))?.click()"
|
||||
},
|
||||
{ "type": "wait", "duration": 2000 }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "step-1",
|
||||
"name": "2단계 메뉴 진입: 회계관리 > 거래처관리",
|
||||
"description": "사이드바를 스크롤하며 회계관리 > 거래처관리 메뉴를 찾아 클릭",
|
||||
"actions": [
|
||||
{
|
||||
"type": "scrollAndFind",
|
||||
"target": "회계관리",
|
||||
"alternativeTexts": ["회계관리", "회계 관리", "Accounting"],
|
||||
"scrollContainer": "sidebar",
|
||||
"maxAttempts": 10,
|
||||
"description": "스크롤하며 회계관리 메뉴 찾기"
|
||||
},
|
||||
{ "type": "click_if_exists", "target": "회계관리", "description": "회계관리 메뉴 클릭" },
|
||||
{ "type": "wait", "duration": 500, "description": "서브메뉴 펼쳐지기 대기" },
|
||||
{
|
||||
"type": "scrollAndFind",
|
||||
"target": "거래처관리",
|
||||
"alternativeTexts": ["거래처관리", "거래처 관리", "Vendors"],
|
||||
"scrollContainer": "submenu",
|
||||
"maxAttempts": 5,
|
||||
"description": "서브메뉴에서 거래처관리 찾기"
|
||||
},
|
||||
{ "type": "click_if_exists", "target": "거래처관리", "description": "거래처관리 메뉴 클릭" },
|
||||
{ "type": "wait", "target": "페이지 로드 완료", "timeout": 10000 }
|
||||
],
|
||||
"expect": {
|
||||
"url": "/accounting/vendors",
|
||||
"pageTitle": "거래처관리",
|
||||
"elements": ["통계 카드", "테이블", "검색창"]
|
||||
},
|
||||
"verification": [
|
||||
"회계관리 메뉴가 펼쳐졌는지 확인",
|
||||
"거래처관리 서브메뉴 클릭 성공",
|
||||
"404 에러 없이 페이지 로드 완료"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
"검색 입력 필드 존재 (placeholder: 거래처명, 거래처코드, 사업자번호 검색...)",
|
||||
"필터 드롭다운 존재 (구분, 신용등급, 거래등급, 악성채권 - Radix combobox)",
|
||||
"테이블 데이터 표시",
|
||||
"API 호출 확인"
|
||||
],
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"전체 거래처 카드 표시",
|
||||
"매출 거래처 카드 표시",
|
||||
"매입 거래처 카드 표시"
|
||||
],
|
||||
"expected": "3개 통계 카드 모두 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
"체크박스 컬럼 (Radix button[role='checkbox'])",
|
||||
"번호 컬럼",
|
||||
"구분 컬럼 (매출/매입/매입매출)",
|
||||
"거래처명 컬럼",
|
||||
"매입 결제일 컬럼",
|
||||
"매출 결제일 컬럼",
|
||||
"신용등급 컬럼",
|
||||
"거래등급 컬럼",
|
||||
"미수금 컬럼",
|
||||
"악성채권 컬럼"
|
||||
],
|
||||
"expected": "10개 컬럼 존재"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "⚠️ 필수 검증: 검색 기능",
|
||||
"description": "검색어 입력 후 테이블 데이터가 필터링되는지 확인",
|
||||
"actions": [
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "(() => { const c = document.querySelectorAll('table tbody tr').length; window.__e2e_beforeSearch = c; return 'beforeSearch=' + c; })()",
|
||||
"description": "검색 전 행 수 저장"
|
||||
},
|
||||
{ "type": "fill", "target": "input[placeholder*='검색']", "value": "가우스", "description": "검색어 '가우스' 입력" },
|
||||
{ "type": "wait", "duration": 1000, "description": "검색 결과 대기" },
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "(() => { const c = document.querySelectorAll('table tbody tr').length; return 'afterSearch=' + c + ', filtered=' + (c < (window.__e2e_beforeSearch||999)); })()",
|
||||
"description": "검색 후 행 수 확인"
|
||||
}
|
||||
],
|
||||
"verify": {
|
||||
"searchApplied": true,
|
||||
"tableContains": "가우스",
|
||||
"dataFiltered": "검색어에 맞는 거래처만 필터링되어야 함"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "검색 결과 데이터 검증",
|
||||
"description": "검색 결과의 각 행에 검색어가 포함되어 있는지 확인",
|
||||
"actions": [
|
||||
{
|
||||
"type": "verify_text",
|
||||
"target": "table tbody",
|
||||
"text": "가우스",
|
||||
"description": "테이블에 가우스 텍스트 존재 확인"
|
||||
}
|
||||
],
|
||||
"verify": {
|
||||
"allRowsContain": "가우스",
|
||||
"verifyMethod": "테이블의 모든 행이 검색어 '가우스'를 포함하는지 확인"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "검색 초기화 및 복원 확인",
|
||||
"description": "검색어 삭제 후 전체 목록 복원 확인",
|
||||
"actions": [
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "(() => { const inp = document.querySelector('input[placeholder*=\"검색\"]'); if(inp){ const nset = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,'value').set; nset.call(inp,''); inp.dispatchEvent(new Event('input',{bubbles:true})); inp.dispatchEvent(new Event('change',{bubbles:true})); return 'cleared'; } return 'not found'; })()",
|
||||
"description": "검색어 삭제"
|
||||
},
|
||||
{ "type": "wait", "duration": 1000, "description": "목록 복원 대기" },
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "(() => { const c = document.querySelectorAll('table tbody tr').length; return 'restored rows=' + c + ', restored=' + (c >= (window.__e2e_beforeSearch||1)); })()",
|
||||
"description": "복원 후 행 수 확인"
|
||||
}
|
||||
],
|
||||
"verify": {
|
||||
"dataRestored": true,
|
||||
"rowCountRestored": "검색 전과 유사한 행 수로 복원"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "구분 필터 테스트 (매출)",
|
||||
"description": "첫 번째 Radix combobox를 클릭하여 '매출' 옵션 선택",
|
||||
"actions": [
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "(async () => { const cbs = document.querySelectorAll('button[role=\"combobox\"]'); if(!cbs[0]) return 'combobox not found'; cbs[0].click(); await new Promise(r=>setTimeout(r,500)); const opt = Array.from(document.querySelectorAll('[role=\"option\"]')).find(o=>o.innerText?.trim()==='매출'); if(opt){ opt.click(); await new Promise(r=>setTimeout(r,1000)); return 'selected 매출, rows=' + document.querySelectorAll('table tbody tr').length; } return 'option 매출 not found'; })()",
|
||||
"description": "구분 필터에서 매출 선택"
|
||||
}
|
||||
],
|
||||
"expected": "매출 거래처만 필터링"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "구분 필터 초기화",
|
||||
"description": "구분 필터를 '전체'로 되돌리기",
|
||||
"actions": [
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "(async () => { const cbs = document.querySelectorAll('button[role=\"combobox\"]'); if(!cbs[0]) return 'combobox not found'; cbs[0].click(); await new Promise(r=>setTimeout(r,500)); const opt = Array.from(document.querySelectorAll('[role=\"option\"]')).find(o=>o.innerText?.trim()==='전체'); if(opt){ opt.click(); await new Promise(r=>setTimeout(r,1000)); return 'selected 전체, rows=' + document.querySelectorAll('table tbody tr').length; } return 'option 전체 not found'; })()",
|
||||
"description": "구분 필터를 전체로 초기화"
|
||||
}
|
||||
],
|
||||
"expected": "전체 데이터 다시 표시"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "테이블 행 클릭 - 상세 페이지 이동",
|
||||
"description": "목록 페이지에서 첫 번째 행을 클릭하여 상세 페이지로 이동",
|
||||
"actions": [
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "(() => { const url = window.location.href; if(!url.includes('/accounting/vendors') || url.includes('mode=')) return 'NOT on list page: ' + url; return 'on list page'; })()",
|
||||
"description": "목록 페이지 확인"
|
||||
},
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "(async () => { const rows = document.querySelectorAll('table tbody tr'); if(rows.length===0) return 'no rows'; rows[0].click(); await new Promise(r=>setTimeout(r,2000)); return 'clicked row, url=' + window.location.href; })()",
|
||||
"description": "첫 번째 행 클릭"
|
||||
}
|
||||
],
|
||||
"expected": "거래처 상세 페이지로 이동"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "상세 페이지 - URL 확인",
|
||||
"action": "verify_url",
|
||||
"target": "/accounting/vendors/\\d+",
|
||||
"checks": [
|
||||
"URL에 거래처 ID 포함 (/accounting/vendors/{id})"
|
||||
],
|
||||
"expected": "URL 정상 전달"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"name": "상세 페이지 - 헤더 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"거래처 상세 타이틀",
|
||||
"목록 버튼 존재",
|
||||
"삭제 버튼 존재",
|
||||
"수정 버튼 존재"
|
||||
],
|
||||
"expected": "상세 페이지 헤더 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"name": "상세 페이지 - 기본 정보 카드 확인",
|
||||
"action": "verify_detail_info",
|
||||
"checks": [
|
||||
"사업자등록번호 필드",
|
||||
"거래처코드 필드",
|
||||
"거래처명 필드",
|
||||
"대표자명 필드",
|
||||
"업태 필드",
|
||||
"업종 필드"
|
||||
],
|
||||
"expected": "기본 정보 모두 표시 (읽기 전용)"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"name": "상세 페이지 - 연락처 정보 확인",
|
||||
"action": "verify_detail_info",
|
||||
"checks": [
|
||||
"주소 필드",
|
||||
"전화번호 필드",
|
||||
"모바일 필드",
|
||||
"팩스 필드",
|
||||
"이메일 필드"
|
||||
],
|
||||
"expected": "연락처 정보 모두 표시"
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"name": "상세 페이지 - 담당자 정보 확인",
|
||||
"action": "verify_detail_info",
|
||||
"checks": [
|
||||
"담당자명 필드",
|
||||
"담당자 전화 필드",
|
||||
"시스템 관리자 필드"
|
||||
],
|
||||
"expected": "담당자 정보 모두 표시"
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"name": "상세 페이지 - 회사 정보 확인",
|
||||
"action": "verify_detail_info",
|
||||
"checks": [
|
||||
"회사 로고 영역",
|
||||
"매입 결제일 필드",
|
||||
"매출 결제일 필드"
|
||||
],
|
||||
"expected": "회사 정보 모두 표시"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"name": "상세 페이지 - 신용/거래 정보 확인",
|
||||
"action": "verify_detail_info",
|
||||
"checks": [
|
||||
"신용등급 필드",
|
||||
"거래등급 필드",
|
||||
"세금계산서 이메일 필드",
|
||||
"입금계좌 은행 필드",
|
||||
"계좌 필드",
|
||||
"예금주 필드"
|
||||
],
|
||||
"expected": "신용/거래 정보 모두 표시"
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"name": "상세 페이지 - 추가 정보 확인",
|
||||
"action": "verify_detail_info",
|
||||
"checks": [
|
||||
"미수금 필드",
|
||||
"악성채권 금액 필드",
|
||||
"악성채권 상태 필드"
|
||||
],
|
||||
"expected": "추가 정보 모두 표시"
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"name": "상세 페이지 - 메모 섹션 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"메모 카드 존재",
|
||||
"메모 리스트 또는 빈 메시지"
|
||||
],
|
||||
"expected": "메모 섹션 표시"
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"name": "핵심 테스트: 수정 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "수정",
|
||||
"expected": "수정 모드로 전환 (URL에 ?mode=edit 추가)"
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"name": "수정 모드 - URL 확인",
|
||||
"action": "verify_url",
|
||||
"target": "mode=edit",
|
||||
"checks": [
|
||||
"URL에 mode=edit 파라미터 포함"
|
||||
],
|
||||
"expected": "수정 모드 URL 정상"
|
||||
},
|
||||
{
|
||||
"id": 23,
|
||||
"name": "수정 모드 - 필드 편집 가능 확인",
|
||||
"action": "verify_edit_mode",
|
||||
"checks": [
|
||||
"거래처명 입력 가능",
|
||||
"대표자명 입력 가능",
|
||||
"전화번호 입력 가능",
|
||||
"이메일 입력 가능",
|
||||
"저장 버튼 존재",
|
||||
"취소 버튼 존재"
|
||||
],
|
||||
"expected": "수정 모드에서 필드 편집 가능"
|
||||
},
|
||||
{
|
||||
"id": 24,
|
||||
"name": "핵심 테스트: 거래처명 수정",
|
||||
"description": "거래처명 input 필드에 테스트 접미사 추가. input에 id/name이 없으므로 value 기반 탐색 필요",
|
||||
"actions": [
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "(async () => { const inputs = document.querySelectorAll('input:not([type=\"hidden\"]):not([type=\"checkbox\"])'); let target = null; inputs.forEach(inp => { if(inp.value && inp.value.length > 1 && !inp.value.includes('수정테스트') && !inp.placeholder.includes('자동생성') && !inp.placeholder.includes('000-00')) { if(!target) target = inp; } }); if(!target) { for(const inp of inputs) { if(inp.value && inp.value.length > 1 && !inp.placeholder.includes('자동생성') && !inp.placeholder.includes('000-00')) { target = inp; break; } } } if(target) { const nset = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,'value').set; const origVal = target.value; nset.call(target, origVal + ' (수정테스트)'); target.dispatchEvent(new Event('input',{bubbles:true})); target.dispatchEvent(new Event('change',{bubbles:true})); window.__e2e_origVendorName = origVal; return 'modified: ' + origVal + ' → ' + target.value; } return 'no editable input found'; })()",
|
||||
"description": "첫 번째 편집 가능 필드(거래처명)에 접미사 추가"
|
||||
}
|
||||
],
|
||||
"expected": "거래처명에 ' (수정테스트)' 추가"
|
||||
},
|
||||
{
|
||||
"id": 25,
|
||||
"name": "핵심 테스트: 저장 버튼 클릭",
|
||||
"description": "저장 버튼 클릭. 이 페이지는 다이얼로그 없이 직접 저장 후 목록으로 리다이렉트됨",
|
||||
"actions": [
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "(() => { window.__e2e_urlBeforeSave = window.location.href; return 'saved url: ' + window.__e2e_urlBeforeSave; })()",
|
||||
"description": "저장 전 URL 기록"
|
||||
},
|
||||
{ "type": "click_if_exists", "target": "저장", "description": "저장 버튼 클릭" },
|
||||
{ "type": "wait", "duration": 2000, "description": "저장 처리 대기" }
|
||||
],
|
||||
"expected": "저장 완료 후 목록 페이지로 리다이렉트"
|
||||
},
|
||||
{
|
||||
"id": 26,
|
||||
"name": "필수 검증 #2: 저장 완료 확인",
|
||||
"description": "저장 후 URL 변경 및 에러 여부 확인 (다이얼로그 없이 직접 저장 방식)",
|
||||
"actions": [
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "(() => { const url = window.location.href; const isListPage = url.includes('/accounting/vendors') && !url.includes('mode='); const hasError = document.body.innerText.includes('404') || document.body.innerText.includes('500') || document.body.innerText.includes('Not Found'); const urlChanged = url !== window.__e2e_urlBeforeSave; return JSON.stringify({ url, isListPage, hasError, urlChanged, result: isListPage && !hasError ? 'PASS' : 'FAIL' }); })()",
|
||||
"description": "저장 후 목록 페이지 복귀 및 에러 없음 확인"
|
||||
}
|
||||
],
|
||||
"expected": "목록 페이지로 복귀, 에러 없음"
|
||||
},
|
||||
{
|
||||
"id": 27,
|
||||
"name": "수정 결과 확인 - 목록에서 검증",
|
||||
"description": "목록 페이지에서 수정된 거래처명 확인",
|
||||
"actions": [
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "(() => { const found = document.body.innerText.includes('수정테스트'); const rows = document.querySelectorAll('table tbody tr').length; return JSON.stringify({ modifiedVisible: found, rowCount: rows, result: found ? 'PASS: 수정된 데이터 목록에 반영' : 'WARN: 수정 텍스트 미표시 (페이지네이션 또는 정렬 영향)' }); })()",
|
||||
"description": "목록에서 수정된 거래처 확인"
|
||||
}
|
||||
],
|
||||
"expected": "수정된 거래처명이 목록에 표시"
|
||||
},
|
||||
{
|
||||
"id": 28,
|
||||
"name": "원래 값 복원 - 수정된 거래처 클릭",
|
||||
"description": "수정된 거래처를 찾아 클릭하여 상세 페이지 진입",
|
||||
"actions": [
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "(async () => { const rows = document.querySelectorAll('table tbody tr'); let target = null; rows.forEach(row => { if(row.innerText.includes('수정테스트')) target = row; }); if(target){ target.click(); await new Promise(r=>setTimeout(r,2000)); return 'clicked modified vendor, url=' + window.location.href; } rows[0]?.click(); await new Promise(r=>setTimeout(r,2000)); return 'modified vendor not found in current page, clicked first row. url=' + window.location.href; })()",
|
||||
"description": "수정된 거래처 행 클릭"
|
||||
}
|
||||
],
|
||||
"expected": "수정된 거래처 상세 페이지 진입"
|
||||
},
|
||||
{
|
||||
"id": 29,
|
||||
"name": "원래 값 복원 - 수정 버튼 클릭",
|
||||
"actions": [
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "(async () => { const btn = Array.from(document.querySelectorAll('button')).find(b=>b.innerText?.trim()==='수정'); if(btn){ btn.click(); await new Promise(r=>setTimeout(r,1500)); return 'edit mode, url=' + window.location.href; } return 'edit button not found'; })()",
|
||||
"description": "수정 모드 진입"
|
||||
}
|
||||
],
|
||||
"expected": "수정 모드로 전환"
|
||||
},
|
||||
{
|
||||
"id": 30,
|
||||
"name": "원래 값 복원 - 거래처명 원복",
|
||||
"description": "거래처명에서 ' (수정테스트)' 제거",
|
||||
"actions": [
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "(async () => { const inputs = document.querySelectorAll('input:not([type=\"hidden\"]):not([type=\"checkbox\"])'); let restored = false; inputs.forEach(inp => { if(inp.value.includes('수정테스트')){ const nset = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,'value').set; const newVal = inp.value.replace(' (수정테스트)',''); nset.call(inp, newVal); inp.dispatchEvent(new Event('input',{bubbles:true})); inp.dispatchEvent(new Event('change',{bubbles:true})); restored = true; } }); return restored ? 'restored' : 'no field with 수정테스트 found'; })()",
|
||||
"description": "접미사 제거하여 원래 값 복원"
|
||||
}
|
||||
],
|
||||
"expected": "거래처명에서 ' (수정테스트)' 제거"
|
||||
},
|
||||
{
|
||||
"id": 31,
|
||||
"name": "원래 값 복원 - 저장",
|
||||
"description": "복원 저장 (다이얼로그 없이 직접 저장)",
|
||||
"actions": [
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "(async () => { const btn = Array.from(document.querySelectorAll('button')).find(b=>b.innerText?.trim()==='저장'); if(btn){ btn.click(); await new Promise(r=>setTimeout(r,2000)); return 'saved, url=' + window.location.href; } return 'save button not found'; })()",
|
||||
"description": "저장 버튼 클릭"
|
||||
}
|
||||
],
|
||||
"expected": "원래 값으로 복원 완료, 목록으로 리다이렉트"
|
||||
},
|
||||
{
|
||||
"id": 32,
|
||||
"name": "원래 값 복원 - 완료 확인",
|
||||
"description": "복원 후 목록 페이지에서 수정테스트 텍스트 제거 확인",
|
||||
"actions": [
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "(() => { const url = window.location.href; const isListPage = url.includes('/accounting/vendors') && !url.includes('mode='); const stillModified = document.body.innerText.includes('수정테스트'); return JSON.stringify({ url, isListPage, stillModified, result: isListPage && !stillModified ? 'PASS: 원복 완료' : 'WARN: 원복 확인 필요' }); })()",
|
||||
"description": "목록에서 원복 확인"
|
||||
}
|
||||
],
|
||||
"expected": "수정테스트 텍스트 제거됨"
|
||||
},
|
||||
{
|
||||
"id": 33,
|
||||
"name": "목록 페이지 최종 확인",
|
||||
"action": "verify_url",
|
||||
"target": "/accounting/vendors",
|
||||
"expected": "거래처관리 목록 페이지 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 34,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body",
|
||||
"expected": "심각한 콘솔 에러 없음"
|
||||
}
|
||||
],
|
||||
"requiredVerifications": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "등록/저장 버튼",
|
||||
"steps": [25, 26],
|
||||
"criteria": "저장 클릭 → 목록 리다이렉트 + 에러 없음 + 데이터 반영"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "등록 버튼 (신규)",
|
||||
"steps": [],
|
||||
"criteria": "보류 - 추후 구현 예정"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "검색/필터",
|
||||
"steps": [6, 7, 8, 9, 10],
|
||||
"criteria": "검색 및 필터 시 데이터 변화 확인"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "삭제 기능",
|
||||
"steps": [],
|
||||
"criteria": "보류 - 테스트 대상에서 제외"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [3],
|
||||
"criteria": "입력 필드, 동작 버튼, API 호출 확인"
|
||||
}
|
||||
],
|
||||
"testData": {
|
||||
"searchKeyword": "가우스",
|
||||
"editSuffix": " (수정테스트)"
|
||||
},
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/clients",
|
||||
"description": "거래처 목록 조회"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"endpoint": "/api/v1/clients/{id}",
|
||||
"description": "거래처 상세 조회"
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"endpoint": "/api/v1/clients/{id}",
|
||||
"description": "거래처 수정"
|
||||
}
|
||||
]
|
||||
}
|
||||
528
_backup_before_enhance/withdrawal-management.json
Normal file
528
_backup_before_enhance/withdrawal-management.json
Normal file
@@ -0,0 +1,528 @@
|
||||
{
|
||||
"enabled": true,
|
||||
"id": "withdrawal-management",
|
||||
"name": "출금관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
},
|
||||
"description": "출금관리 목록 조회, 계정과목명 일괄변경, 상세 수정 기능 E2E 테스트",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
"url": "/ko/accounting/withdrawals",
|
||||
"navigation": {
|
||||
"targetUrl": "/accounting/withdrawals",
|
||||
"urlPattern": "/accounting/withdrawals|/ko/accounting/withdrawals",
|
||||
"menuHints": ["출금관리", "출금 관리", "회계관리"]
|
||||
},
|
||||
"menuNavigation": {
|
||||
"level1": "회계관리",
|
||||
"level2": "출금관리",
|
||||
"expectedUrl": "/ko/accounting/withdrawals",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
},
|
||||
"menuNavigationEnhanced": {
|
||||
"strategy": "scroll-and-search",
|
||||
"sidebarSelector": ".sidebar-scroll, [data-sidebar], nav[role='navigation']",
|
||||
"scrollBehavior": {
|
||||
"direction": "down",
|
||||
"step": 200,
|
||||
"maxScrolls": 10,
|
||||
"waitAfterScroll": 300
|
||||
},
|
||||
"level1": {
|
||||
"text": "회계관리",
|
||||
"expandable": true,
|
||||
"waitAfterClick": 500
|
||||
},
|
||||
"level2": {
|
||||
"text": "출금관리",
|
||||
"waitAfterClick": 300
|
||||
},
|
||||
"fallbackUrl": "/ko/accounting/withdrawals",
|
||||
"verification": {
|
||||
"urlContains": "/accounting/withdrawals",
|
||||
"timeout": 5000
|
||||
}
|
||||
},
|
||||
"timeout": 60000,
|
||||
"tags": ["accounting", "withdrawal", "crud"],
|
||||
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
|
||||
"steps": [
|
||||
{
|
||||
"id": "step-0",
|
||||
"name": "사이드바 메뉴 전체 펼치기",
|
||||
"description": "모두 펼치기 버튼을 클릭하여 전체 메뉴를 펼친 후 메뉴 탐색 준비",
|
||||
"actions": [
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "document.querySelector('.sidebar-scroll')?.scrollTo({top:0,behavior:'instant'})"
|
||||
},
|
||||
{ "type": "wait", "duration": 300 },
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "Array.from(document.querySelectorAll('button')).find(b => b.innerText?.includes('모두 펼치기'))?.click()"
|
||||
},
|
||||
{ "type": "wait", "duration": 2000 }
|
||||
],
|
||||
"expect": {
|
||||
"sidebarReady": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-1",
|
||||
"name": "출금관리 메뉴 진입",
|
||||
"description": "회계관리 > 출금관리 메뉴로 이동 (scrollAndFind 패턴 사용)",
|
||||
"menuNavigation": {
|
||||
"useEnhanced": true,
|
||||
"scrollAndFind": {
|
||||
"level1": {
|
||||
"text": "회계관리",
|
||||
"scrollUntilVisible": true,
|
||||
"clickToExpand": true,
|
||||
"waitAfterClick": 500
|
||||
},
|
||||
"level2": {
|
||||
"text": "출금관리",
|
||||
"scrollUntilVisible": true,
|
||||
"waitAfterClick": 300
|
||||
}
|
||||
},
|
||||
"fallback": {
|
||||
"useDirectUrl": true,
|
||||
"url": "/ko/accounting/withdrawals"
|
||||
}
|
||||
},
|
||||
"expect": {
|
||||
"url": "/accounting/withdrawals",
|
||||
"visible": ["출금관리", "총 출금"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-2",
|
||||
"name": "목록 페이지 구조 확인",
|
||||
"description": "테이블 및 필터 요소 확인",
|
||||
"expect": {
|
||||
"visible": ["출금일", "출금계좌", "받는분", "출금금액", "거래처", "적요", "출금유형"],
|
||||
"elements": {
|
||||
"statisticsCards": ["총 출금", "당월 출금", "거래처 미설정", "출금유형 미설정"],
|
||||
"filters": ["계정과목명", "저장", "새로고침"],
|
||||
"pagination": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-3",
|
||||
"name": "계정과목명 드롭다운 옵션 확인",
|
||||
"description": "계정과목명 일괄변경 드롭다운 옵션 검증",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "계정과목명 드롭다운", "description": "드롭다운 열기" }
|
||||
],
|
||||
"expect": {
|
||||
"options": ["미설정", "매입대금", "급여", "임차료", "수도광열비", "통신비", "소모품비", "운반비", "차량유지비", "보험료", "세금과공과", "이자비용", "수수료", "기타"]
|
||||
},
|
||||
"note": "출금유형 옵션은 비용 계정 기준이므로 입금관리와 다름"
|
||||
},
|
||||
{
|
||||
"id": "step-4",
|
||||
"name": "체크박스 선택 후 계정과목명 일괄변경",
|
||||
"description": "테이블 행 선택 후 계정과목명 일괄변경 저장",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "첫 번째 행 체크박스", "description": "행 선택" },
|
||||
{ "type": "click_if_exists", "target": "계정과목명 드롭다운", "description": "드롭다운 열기" },
|
||||
{ "type": "click_if_exists", "target": "매입대금", "description": "매입대금 선택" },
|
||||
{ "type": "click_if_exists", "target": "저장", "description": "저장 버튼 클릭" }
|
||||
],
|
||||
"expect": {
|
||||
"dialog": "확인 다이얼로그 표시",
|
||||
"dialogMessage": "1개의 출금 유형을 매입대금(으)로 모두 변경하시겠습니까?",
|
||||
"toast": "변경 완료 메시지"
|
||||
},
|
||||
"checks": [
|
||||
"API 호출 확인 (PUT /api/v1/withdrawals/batch-update-account)",
|
||||
"성공 토스트 메시지",
|
||||
"URL 유지 확인"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "step-4-1",
|
||||
"name": "⚠️ 필수 검증: 계정과목명 변경 데이터 반영 확인",
|
||||
"note": "토스트 성공 메시지만으로 PASS 판정 불가. 실제 데이터 변경 확인 필수!",
|
||||
"description": "저장 후 테이블에서 변경된 출금유형 값 확인",
|
||||
"expect": {
|
||||
"tableCell": {
|
||||
"row": 1,
|
||||
"column": "출금유형",
|
||||
"value": "매입대금"
|
||||
}
|
||||
},
|
||||
"checks": [
|
||||
"선택한 행의 출금유형 컬럼 값 확인",
|
||||
"변경 전 값과 비교 (예: 미설정 → 매입대금)",
|
||||
"페이지 새로고침 후에도 변경된 값 유지 확인",
|
||||
"API 응답과 UI 표시값 일치 확인"
|
||||
],
|
||||
"knownBugReference": "BUG-DEPOSIT-20260115-001 (입금관리 동일 버그 확인 필요)"
|
||||
},
|
||||
{
|
||||
"id": "step-5",
|
||||
"name": "출금 상세 페이지 이동",
|
||||
"description": "테이블 행 클릭하여 상세 페이지로 이동",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "테이블 첫 번째 행", "description": "행 클릭 (체크박스 제외 영역)" }
|
||||
],
|
||||
"expect": {
|
||||
"url": "/accounting/withdrawals/{id}",
|
||||
"visible": ["출금 상세", "기본 정보", "목록", "삭제", "수정"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-6",
|
||||
"name": "상세 페이지 읽기 모드 필드 확인",
|
||||
"description": "수정 전 필드들이 비활성화 상태인지 확인",
|
||||
"expect": {
|
||||
"fields": [
|
||||
{ "name": "출금일", "disabled": true },
|
||||
{ "name": "출금계좌", "disabled": true },
|
||||
{ "name": "받는분", "disabled": true },
|
||||
{ "name": "출금금액", "disabled": true },
|
||||
{ "name": "적요", "disabled": true },
|
||||
{ "name": "거래처", "disabled": true },
|
||||
{ "name": "출금 유형", "disabled": true }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-7",
|
||||
"name": "수정 모드 전환",
|
||||
"description": "수정 버튼 클릭하여 편집 모드로 전환",
|
||||
"click": "수정",
|
||||
"expect": {
|
||||
"url": "/accounting/withdrawals/{id}?mode=edit",
|
||||
"visible": ["출금 수정", "취소", "저장"],
|
||||
"notVisible": ["목록", "삭제", "수정"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-8",
|
||||
"name": "수정 모드 필드 활성화 검증",
|
||||
"description": "수정 가능한 필드와 불가능한 필드 확인",
|
||||
"expect": {
|
||||
"fields": [
|
||||
{ "name": "출금일", "disabled": true, "note": "은행데이터 - 수정 불가" },
|
||||
{ "name": "출금계좌", "disabled": true, "note": "은행데이터 - 수정 불가" },
|
||||
{ "name": "받는분", "disabled": true, "note": "은행데이터 - 수정 불가" },
|
||||
{ "name": "출금금액", "disabled": true, "note": "은행데이터 - 수정 불가" },
|
||||
{ "name": "적요", "disabled": false, "editable": true },
|
||||
{ "name": "거래처", "disabled": false, "type": "combobox", "editable": true },
|
||||
{ "name": "출금 유형", "disabled": false, "type": "combobox", "editable": true }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-9",
|
||||
"name": "거래처 드롭다운 옵션 확인",
|
||||
"description": "거래처 선택 드롭다운 옵션 검증",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "거래처 드롭다운", "description": "드롭다운 열기" }
|
||||
],
|
||||
"expect": {
|
||||
"options": ["거래처테스트", "아크더레드", "코브라브릿지", "가우스전자", "아크아크"],
|
||||
"note": "거래처 옵션은 시스템 공통 데이터"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-10",
|
||||
"name": "출금 유형 드롭다운 옵션 확인",
|
||||
"description": "출금 유형 선택 드롭다운 옵션 검증",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "출금 유형 드롭다운", "description": "드롭다운 열기" }
|
||||
],
|
||||
"expect": {
|
||||
"options": ["미설정", "매입대금", "급여", "임차료", "수도광열비", "통신비", "소모품비", "운반비", "차량유지비", "보험료", "세금과공과", "이자비용", "수수료", "기타"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-11",
|
||||
"name": "수정 데이터 입력",
|
||||
"description": "수정 가능한 필드에 테스트 데이터 입력",
|
||||
"form": {
|
||||
"fields": [
|
||||
{ "name": "적요", "type": "text", "value": "테스트 적요 수정" }
|
||||
]
|
||||
},
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "거래처 드롭다운", "description": "거래처 드롭다운 열기" },
|
||||
{ "type": "click_if_exists", "target": "거래처테스트", "description": "거래처 선택" },
|
||||
{ "type": "click_if_exists", "target": "출금 유형 드롭다운", "description": "출금 유형 드롭다운 열기" },
|
||||
{ "type": "click_if_exists", "target": "매입대금", "description": "매입대금 선택" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "step-12",
|
||||
"name": "저장 및 결과 확인",
|
||||
"description": "저장 버튼 클릭 후 데이터 반영 확인",
|
||||
"click": "저장",
|
||||
"expect": {
|
||||
"toast": "저장 완료 메시지",
|
||||
"url": "/accounting/withdrawals/{id}",
|
||||
"mode": "view"
|
||||
},
|
||||
"checks": [
|
||||
"API 호출 확인 (PUT /api/v1/withdrawals/{id})",
|
||||
"성공 토스트 메시지",
|
||||
"URL 유지 확인 (에러 페이지 이동 금지)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "step-12-1",
|
||||
"name": "⚠️ 필수 검증: 수정 데이터 반영 확인",
|
||||
"note": "토스트 성공 메시지만으로 PASS 판정 불가. 실제 데이터 변경 확인 필수!",
|
||||
"description": "저장 후 상세 페이지에서 변경된 값 확인",
|
||||
"expect": {
|
||||
"fields": [
|
||||
{ "name": "적요", "value": "테스트 적요 수정" },
|
||||
{ "name": "거래처", "value": "거래처테스트" },
|
||||
{ "name": "출금 유형", "value": "매입대금" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-13",
|
||||
"name": "취소 버튼 동작 확인",
|
||||
"description": "수정 모드에서 취소 버튼 동작 검증",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "수정", "description": "수정 모드 진입" },
|
||||
{ "type": "click_if_exists", "target": "취소", "description": "취소 버튼 클릭" }
|
||||
],
|
||||
"expect": {
|
||||
"url": "/accounting/withdrawals/{id}",
|
||||
"mode": "view",
|
||||
"visible": ["출금 상세", "목록", "삭제", "수정"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-14",
|
||||
"name": "목록 버튼 동작 확인",
|
||||
"description": "목록 버튼 클릭하여 목록 페이지로 이동",
|
||||
"click": "목록",
|
||||
"expect": {
|
||||
"url": "/accounting/withdrawals",
|
||||
"visible": ["출금관리", "총 출금"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-15",
|
||||
"name": "필터 드롭다운 검증",
|
||||
"description": "목록 페이지 필터 드롭다운 옵션 확인",
|
||||
"note": "3개의 필터 드롭다운 존재 (거래처, 출금유형, 정렬)",
|
||||
"expect": {
|
||||
"filters": [
|
||||
{ "name": "거래처 필터", "default": "전체" },
|
||||
{ "name": "출금유형 필터", "default": "전체" },
|
||||
{ "name": "정렬", "default": "최신순", "options": ["최신순", "등록순", "금액 높은순", "금액 낮은순"] }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-16",
|
||||
"name": "날짜 필터 검증",
|
||||
"description": "날짜 필터 버튼 동작 확인",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "당해년도", "description": "당해년도 버튼 클릭" }
|
||||
],
|
||||
"expect": {
|
||||
"dateRange": {
|
||||
"start": "2026-01-01",
|
||||
"end": "2026-12-31"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-17",
|
||||
"name": "페이지네이션 동작 확인",
|
||||
"description": "페이지네이션 버튼 동작 검증 (데이터 존재 시)",
|
||||
"condition": "데이터가 20건 이상인 경우에만 실행",
|
||||
"expect": {
|
||||
"pagination": {
|
||||
"itemsPerPage": 20,
|
||||
"currentPage": 1
|
||||
}
|
||||
},
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "다음", "description": "다음 페이지로 이동" }
|
||||
],
|
||||
"expectAfterAction": {
|
||||
"currentPage": 2
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
"skipTests": [
|
||||
{
|
||||
"id": "delete-button",
|
||||
"name": "삭제 버튼 테스트",
|
||||
"reason": "사용자 요청에 따라 테스트 제외"
|
||||
}
|
||||
],
|
||||
|
||||
"knownBugs": [
|
||||
{
|
||||
"id": "BUG-DEPOSIT-20260115-001",
|
||||
"description": "계정과목명 일괄변경 시 API 오류 발생 (입금관리)",
|
||||
"errorMessage": "존재하지 않는 URI 또는 데이터",
|
||||
"relatedSteps": ["step-4-1"],
|
||||
"note": "출금관리에서도 동일한 버그가 존재할 수 있으므로 step-4-1에서 검증 필수"
|
||||
},
|
||||
{
|
||||
"id": "BUG-SALES-20260115-001",
|
||||
"description": "계정과목명 일괄변경 시 토스트 성공 표시되나 실제 데이터 미변경 (매출관리)",
|
||||
"relatedSteps": ["step-4-1"],
|
||||
"note": "유사한 UI 패턴이므로 동일 버그 가능성 있음"
|
||||
}
|
||||
],
|
||||
|
||||
"criticalValidationChecklist": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "파일 다운로드 검증",
|
||||
"trigger": "다운로드, Export 버튼 발견 시",
|
||||
"checks": ["Network API 호출", "실제 파일 다운로드"],
|
||||
"note": "Console LOG만으로 PASS 판정 금지"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "등록/저장 버튼 검증",
|
||||
"trigger": "등록, 저장, 제출 버튼 클릭 시",
|
||||
"checks": ["URL 유지 확인", "에러 페이지 없음", "성공 토스트"],
|
||||
"note": "에러 페이지 이동 감지 필수"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "일괄변경 데이터 반영 검증",
|
||||
"trigger": "계정과목명 저장 후",
|
||||
"checks": ["테이블 데이터 변경 확인", "새로고침 후 유지 확인"],
|
||||
"note": "토스트만 확인하면 불충분"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "목업 페이지 감지",
|
||||
"trigger": "페이지 로드 시",
|
||||
"checks": ["입력 필드 존재", "동작하는 버튼 존재", "API 호출 여부"],
|
||||
"note": "버튼만 있고 동작 안하면 목업"
|
||||
}
|
||||
],
|
||||
|
||||
"testData": {
|
||||
"sampleWithdrawal": {
|
||||
"date": "2025-12-28",
|
||||
"account": "운영계좌",
|
||||
"recipient": "홍길동",
|
||||
"amount": "1,500,000",
|
||||
"vendor": "",
|
||||
"description": "급여 지급",
|
||||
"withdrawalType": "미설정"
|
||||
},
|
||||
"modifiedData": {
|
||||
"description": "테스트 적요 수정",
|
||||
"vendor": "거래처테스트",
|
||||
"withdrawalType": "매입대금"
|
||||
}
|
||||
},
|
||||
|
||||
"pageStructure": {
|
||||
"listPage": {
|
||||
"url": "/accounting/withdrawals",
|
||||
"title": "출금관리",
|
||||
"statistics": ["총 출금", "당월 출금", "거래처 미설정", "출금유형 미설정"],
|
||||
"tableColumns": ["checkbox", "출금일", "출금계좌", "받는분", "출금금액", "거래처", "적요", "출금유형", "action"],
|
||||
"batchUpdate": {
|
||||
"label": "계정과목명",
|
||||
"saveButton": "저장"
|
||||
},
|
||||
"filters": ["거래처", "출금유형", "정렬"],
|
||||
"dateFilters": ["당해년도", "전전월", "전월", "당월", "어제", "오늘"]
|
||||
},
|
||||
"detailPage": {
|
||||
"url": "/accounting/withdrawals/{id}",
|
||||
"title": "출금 상세",
|
||||
"buttons": ["목록", "삭제", "수정"],
|
||||
"fields": {
|
||||
"readOnly": ["출금일", "출금계좌", "받는분", "출금금액"],
|
||||
"editable": ["적요", "거래처", "출금 유형"]
|
||||
}
|
||||
},
|
||||
"editPage": {
|
||||
"url": "/accounting/withdrawals/{id}?mode=edit",
|
||||
"title": "출금 수정",
|
||||
"buttons": ["취소", "저장"]
|
||||
}
|
||||
},
|
||||
|
||||
"dropdownOptions": {
|
||||
"accountSubject": {
|
||||
"label": "계정과목명",
|
||||
"options": ["미설정", "매입대금", "급여", "임차료", "수도광열비", "통신비", "소모품비", "운반비", "차량유지비", "보험료", "세금과공과", "이자비용", "수수료", "기타"],
|
||||
"note": "출금유형은 비용 계정 기준 (입금유형과 다름)"
|
||||
},
|
||||
"withdrawalType": {
|
||||
"label": "출금 유형",
|
||||
"options": ["미설정", "매입대금", "급여", "임차료", "수도광열비", "통신비", "소모품비", "운반비", "차량유지비", "보험료", "세금과공과", "이자비용", "수수료", "기타"]
|
||||
},
|
||||
"vendor": {
|
||||
"label": "거래처",
|
||||
"options": ["거래처테스트", "아크더레드", "코브라브릿지", "가우스전자", "아크아크"]
|
||||
},
|
||||
"sortOrder": {
|
||||
"label": "정렬",
|
||||
"options": ["최신순", "등록순", "금액 높은순", "금액 낮은순"]
|
||||
}
|
||||
},
|
||||
|
||||
"comparisonWithDeposit": {
|
||||
"differences": [
|
||||
{
|
||||
"field": "계정과목/유형 옵션",
|
||||
"deposit": "매출대금, 선수금, 가수금, 임대수익, 이자수익, 보증금 반환, 차입금, 자본금, 부가세 환급, 기타 (수입 계정)",
|
||||
"withdrawal": "매입대금, 급여, 임차료, 수도광열비, 통신비, 소모품비, 운반비, 차량유지비, 보험료, 세금과공과, 이자비용, 수수료, 기타 (비용 계정)"
|
||||
},
|
||||
{
|
||||
"field": "테이블 컬럼명",
|
||||
"deposit": "입금일, 입금계좌, 입금자명, 입금금액, 입금유형",
|
||||
"withdrawal": "출금일, 출금계좌, 받는분, 출금금액, 출금유형"
|
||||
},
|
||||
{
|
||||
"field": "통계 카드",
|
||||
"deposit": "총 입금, 당월 입금, 입금유형 미설정",
|
||||
"withdrawal": "총 출금, 당월 출금, 출금유형 미설정"
|
||||
}
|
||||
],
|
||||
"similarities": [
|
||||
"페이지 구조 (목록 → 상세 → 수정)",
|
||||
"계정과목명 일괄변경 기능",
|
||||
"거래처 드롭다운 옵션 (공통 데이터)",
|
||||
"날짜 필터 버튼 (당해년도, 전전월, 전월, 당월, 어제, 오늘)",
|
||||
"정렬 옵션 (최신순, 등록순, 금액 높은순, 금액 낮은순)",
|
||||
"은행 데이터 필드 수정 불가 (날짜, 계좌, 금액 등)"
|
||||
]
|
||||
},
|
||||
|
||||
"assertions": [
|
||||
{
|
||||
"type": "url",
|
||||
"expected": "/accounting/withdrawals",
|
||||
"message": "목록 페이지 URL 확인"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"target": "body",
|
||||
"expected": "출금관리",
|
||||
"message": "페이지 타이틀 확인"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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,11 +41,22 @@
|
||||
"level2": "악성채권추심관리",
|
||||
"expected": {
|
||||
"url_contains": "/accounting",
|
||||
"visible": ["악성채권", "추심"]
|
||||
"visible": [
|
||||
"악성채권",
|
||||
"추심"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "URL 검증",
|
||||
"action": "verify_url",
|
||||
"expected": {
|
||||
"url_contains": "/accounting/bad-debt-collection"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
@@ -49,7 +67,13 @@
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"id": 4,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const cards = document.querySelectorAll('[class*=\"card\"], [class*=\"Card\"], [class*=\"stat\"], [class*=\"Stat\"], [class*=\"summary\"]');\n const texts = Array.from(cards).map(c => c.innerText?.substring(0, 30)).filter(Boolean);\n return texts.length > 0 ? 'Stats: ' + texts.length + ' cards found' : 'No stat cards (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "악성채권 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
@@ -62,7 +86,13 @@
|
||||
"expected": "악성채권 테이블 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"id": 6,
|
||||
"name": "목록 필터 테스트",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const selects = document.querySelectorAll('select, [role=\"combobox\"], button[class*=\"select\"], button[class*=\"Select\"]');\n if (selects.length > 0) {\n return 'Filters found: ' + selects.length;\n }\n return 'No filter dropdowns (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -73,7 +103,7 @@
|
||||
"expected": "통계 정보 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"id": 8,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 채권 등록 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
@@ -83,7 +113,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"id": 9,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 거래처 선택",
|
||||
"action": "click_if_exists",
|
||||
@@ -91,14 +121,14 @@
|
||||
"expected": "거래처 선택 가능"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"id": 10,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 채권금액 입력",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[name*='amount'], input[placeholder*='금액']"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"id": 11,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 필수 검증 #2: 채권 저장",
|
||||
"action": "click_if_exists",
|
||||
@@ -112,14 +142,23 @@
|
||||
"expected": "채권 등록 완료"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"id": 12,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 저장 완료 토스트 확인",
|
||||
"action": "verify_toast",
|
||||
"verify": {
|
||||
"contains": "등록|완료|성공|저장"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 등록된 채권 검색",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[type='search'], input[placeholder*='검색']"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"id": 14,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 등록된 채권 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -129,7 +168,7 @@
|
||||
"expected": "등록된 채권 확인"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"id": 15,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 채권 상세 조회",
|
||||
"action": "click_if_exists",
|
||||
@@ -139,7 +178,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"id": 16,
|
||||
"name": "상세 정보 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -150,7 +189,7 @@
|
||||
"expected": "상세 정보 표시"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"id": 17,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 상태 변경",
|
||||
"action": "click_if_exists",
|
||||
@@ -158,14 +197,14 @@
|
||||
"expected": "상태 변경 가능"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"id": 18,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 추심 메모 추가",
|
||||
"action": "click_if_exists",
|
||||
"target": "textarea[name*='memo'], textarea[placeholder*='메모']"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"id": 19,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 변경 저장",
|
||||
"action": "click_if_exists",
|
||||
@@ -177,7 +216,16 @@
|
||||
"expected": "채권 정보 수정 완료"
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"id": 20,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 완료 토스트 확인",
|
||||
"action": "verify_toast",
|
||||
"verify": {
|
||||
"contains": "수정|완료|성공|저장"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 채권 삭제",
|
||||
"action": "click_if_exists",
|
||||
@@ -187,7 +235,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"id": 22,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 삭제 확인",
|
||||
"action": "click_if_exists",
|
||||
@@ -199,7 +247,7 @@
|
||||
"expected": "채권 삭제 완료"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"id": 23,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 삭제 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -207,6 +255,12 @@
|
||||
"E2E_TEST_채권거래처 목록에서 제거"
|
||||
],
|
||||
"expected": "채권 삭제 반영"
|
||||
},
|
||||
{
|
||||
"id": 24,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
@@ -240,13 +294,18 @@
|
||||
{
|
||||
"id": 2,
|
||||
"name": "저장 버튼",
|
||||
"steps": [8, 15],
|
||||
"steps": [
|
||||
8,
|
||||
15
|
||||
],
|
||||
"criteria": "API 호출 + 성공 토스트 + 데이터 반영"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"steps": [
|
||||
2
|
||||
],
|
||||
"criteria": "악성채권 목록, 등록 버튼, 상태 필터 존재"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -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,11 +34,22 @@
|
||||
"level2": "입출금계좌조회",
|
||||
"expected": {
|
||||
"url_contains": "/accounting",
|
||||
"visible": ["입출금", "계좌"]
|
||||
"visible": [
|
||||
"입출금",
|
||||
"계좌"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "URL 검증",
|
||||
"action": "verify_url",
|
||||
"expected": {
|
||||
"url_contains": "/accounting/bank-transactions"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
@@ -42,7 +60,13 @@
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"id": 4,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const cards = document.querySelectorAll('[class*=\"card\"], [class*=\"Card\"], [class*=\"stat\"], [class*=\"Stat\"], [class*=\"summary\"]');\n const texts = Array.from(cards).map(c => c.innerText?.substring(0, 30)).filter(Boolean);\n return texts.length > 0 ? 'Stats: ' + texts.length + ' cards found' : 'No stat cards (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "거래내역 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
@@ -55,7 +79,13 @@
|
||||
"expected": "거래내역 테이블 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"id": 6,
|
||||
"name": "목록 필터 테스트",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const selects = document.querySelectorAll('select, [role=\"combobox\"], button[class*=\"select\"], button[class*=\"Select\"]');\n if (selects.length > 0) {\n return 'Filters found: ' + selects.length;\n }\n return 'No filter dropdowns (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "계좌 선택 드롭다운 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -64,7 +94,7 @@
|
||||
"expected": "계좌 선택 가능"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"id": 8,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 기간 필터 - 시작일",
|
||||
"action": "click_if_exists",
|
||||
@@ -72,7 +102,7 @@
|
||||
"expected": "날짜 선택 열림"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"id": 9,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 기간 필터 적용",
|
||||
"action": "click_if_exists",
|
||||
@@ -80,7 +110,7 @@
|
||||
"expected": "필터 적용됨"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"id": 10,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 필터 결과 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -90,7 +120,7 @@
|
||||
"expected": "필터 동작 확인"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"id": 11,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 거래 상세 보기",
|
||||
"action": "click_if_exists",
|
||||
@@ -100,7 +130,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"id": 12,
|
||||
"name": "상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
@@ -111,14 +141,14 @@
|
||||
"expected": "거래 상세 정보 표시"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"id": 13,
|
||||
"name": "목록으로 돌아가기",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('목록'), a:has-text('목록'), [class*='back']",
|
||||
"expected": "목록 페이지로 복귀"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"id": 14,
|
||||
"name": "입금 합계 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -127,7 +157,7 @@
|
||||
"expected": "입금 합계 표시"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"id": 15,
|
||||
"name": "출금 합계 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -136,7 +166,7 @@
|
||||
"expected": "출금 합계 표시"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"id": 16,
|
||||
"name": "엑셀 다운로드 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -145,7 +175,7 @@
|
||||
"expected": "엑셀 다운로드 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"id": 17,
|
||||
"name": "인쇄 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -154,13 +184,19 @@
|
||||
"expected": "인쇄 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"id": 18,
|
||||
"name": "페이지네이션 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"페이지 번호 표시"
|
||||
],
|
||||
"expected": "페이지네이션 표시"
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
@@ -179,13 +215,19 @@
|
||||
{
|
||||
"id": 3,
|
||||
"name": "검색/필터",
|
||||
"steps": [5, 6, 7],
|
||||
"steps": [
|
||||
5,
|
||||
6,
|
||||
7
|
||||
],
|
||||
"criteria": "기간 필터 동작"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"steps": [
|
||||
2
|
||||
],
|
||||
"criteria": "거래내역 목록, 계좌 선택, 기간 필터 존재"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -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",
|
||||
@@ -39,11 +46,22 @@
|
||||
"level2": "어음관리",
|
||||
"expected": {
|
||||
"url_contains": "/accounting/bills",
|
||||
"visible": ["어음관리", "어음"]
|
||||
"visible": [
|
||||
"어음관리",
|
||||
"어음"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "URL 검증",
|
||||
"action": "verify_url",
|
||||
"expected": {
|
||||
"url_contains": "/accounting/bills"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
@@ -54,7 +72,13 @@
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"id": 4,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const cards = document.querySelectorAll('[class*=\"card\"], [class*=\"Card\"], [class*=\"stat\"], [class*=\"Stat\"], [class*=\"summary\"]');\n const texts = Array.from(cards).map(c => c.innerText?.substring(0, 30)).filter(Boolean);\n return texts.length > 0 ? 'Stats: ' + texts.length + ' cards found' : 'No stat cards (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "어음 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
@@ -67,7 +91,13 @@
|
||||
"expected": "어음 테이블 컬럼 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"id": 6,
|
||||
"name": "목록 필터 테스트",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const selects = document.querySelectorAll('select, [role=\"combobox\"], button[class*=\"select\"], button[class*=\"Select\"]');\n if (selects.length > 0) {\n return 'Filters found: ' + selects.length;\n }\n return 'No filter dropdowns (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "검색 기능 테스트",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[placeholder*='검색']",
|
||||
@@ -77,7 +107,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"id": 8,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 어음 등록 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
@@ -88,21 +118,41 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"id": 9,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 어음 정보 입력",
|
||||
"action": "fill_form",
|
||||
"fields": [
|
||||
{"name": "어음번호", "type": "text", "value": "E2E_TEST_어음_{timestamp}"},
|
||||
{"name": "금액", "type": "number", "value": "1000000"},
|
||||
{"name": "만기일", "type": "date", "value": "2026-03-15"},
|
||||
{"name": "발행처", "type": "text", "value": "테스트발행처"},
|
||||
{"name": "메모", "type": "text", "value": "E2E 자동화 테스트 어음"}
|
||||
{
|
||||
"name": "어음번호",
|
||||
"type": "text",
|
||||
"value": "E2E_TEST_어음_{timestamp}"
|
||||
},
|
||||
{
|
||||
"name": "금액",
|
||||
"type": "number",
|
||||
"value": "1000000"
|
||||
},
|
||||
{
|
||||
"name": "만기일",
|
||||
"type": "date",
|
||||
"value": "2026-03-15"
|
||||
},
|
||||
{
|
||||
"name": "발행처",
|
||||
"type": "text",
|
||||
"value": "테스트발행처"
|
||||
},
|
||||
{
|
||||
"name": "메모",
|
||||
"type": "text",
|
||||
"value": "E2E 자동화 테스트 어음"
|
||||
}
|
||||
],
|
||||
"note": "타임스탬프로 고유성 보장"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"id": 10,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 필수 검증 #2: 등록 저장",
|
||||
"action": "click_if_exists",
|
||||
@@ -116,36 +166,52 @@
|
||||
"expected": "어음 등록 완료"
|
||||
},
|
||||
{
|
||||
"id": "7-modal-close",
|
||||
"id": 11,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 저장 완료 토스트 확인",
|
||||
"action": "verify_toast",
|
||||
"verify": {
|
||||
"contains": "등록|완료|성공|저장"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 모달 닫기 확인",
|
||||
"action": "close_modal_if_open",
|
||||
"expected": "모달 닫힘"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"id": 13,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 등록 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"search": "E2E_TEST_어음",
|
||||
"expected": {
|
||||
"row_exists": true,
|
||||
"contains": ["E2E", "1,000,000"]
|
||||
"contains": [
|
||||
"E2E",
|
||||
"1,000,000"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"id": 14,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 어음 상세 페이지 진입",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:has-text('E2E')",
|
||||
"expected": {
|
||||
"url_contains": "/accounting/bills/",
|
||||
"visible": ["어음 상세", "수정", "삭제"]
|
||||
"visible": [
|
||||
"어음 상세",
|
||||
"수정",
|
||||
"삭제"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"id": 15,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -158,7 +224,7 @@
|
||||
"expected": "입력한 데이터와 일치"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"id": 16,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 모드 진입",
|
||||
"action": "click_if_exists",
|
||||
@@ -169,7 +235,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"id": 17,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 메모 수정",
|
||||
"action": "click_if_exists",
|
||||
@@ -178,7 +244,7 @@
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"id": 18,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 필수 검증 #2: 수정 저장",
|
||||
"action": "click_if_exists",
|
||||
@@ -192,7 +258,16 @@
|
||||
"expected": "수정 완료"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"id": 19,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 완료 토스트 확인",
|
||||
"action": "verify_toast",
|
||||
"verify": {
|
||||
"contains": "수정|완료|성공|저장"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 결과 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -202,7 +277,7 @@
|
||||
"expected": "수정된 데이터 반영"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"id": 21,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 삭제 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
@@ -213,7 +288,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"id": 22,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 필수 검증 #6: 삭제 확인",
|
||||
"action": "click_if_exists",
|
||||
@@ -226,7 +301,7 @@
|
||||
"expected": "삭제 완료 및 목록 복귀"
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"id": 23,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 삭제 결과 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -235,6 +310,12 @@
|
||||
"row_exists": false,
|
||||
"message": "테스트 어음이 목록에서 제거됨"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 24,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
@@ -268,19 +349,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 + 목록에서 제거"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -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,11 +34,22 @@
|
||||
"level2": "카드내역조회",
|
||||
"expected": {
|
||||
"url_contains": "/accounting",
|
||||
"visible": ["카드", "내역"]
|
||||
"visible": [
|
||||
"카드",
|
||||
"내역"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "URL 검증",
|
||||
"action": "verify_url",
|
||||
"expected": {
|
||||
"url_contains": "/accounting/card-transactions"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
@@ -42,7 +60,13 @@
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"id": 4,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const cards = document.querySelectorAll('[class*=\"card\"], [class*=\"Card\"], [class*=\"stat\"], [class*=\"Stat\"], [class*=\"summary\"]');\n const texts = Array.from(cards).map(c => c.innerText?.substring(0, 30)).filter(Boolean);\n return texts.length > 0 ? 'Stats: ' + texts.length + ' cards found' : 'No stat cards (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "카드내역 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
@@ -55,7 +79,13 @@
|
||||
"expected": "카드내역 테이블 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"id": 6,
|
||||
"name": "목록 필터 테스트",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const selects = document.querySelectorAll('select, [role=\"combobox\"], button[class*=\"select\"], button[class*=\"Select\"]');\n if (selects.length > 0) {\n return 'Filters found: ' + selects.length;\n }\n return 'No filter dropdowns (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "카드 선택 드롭다운 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -64,7 +94,7 @@
|
||||
"expected": "카드 선택 가능"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"id": 8,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 기간 필터 - 시작일",
|
||||
"action": "click_if_exists",
|
||||
@@ -72,7 +102,7 @@
|
||||
"expected": "날짜 선택 열림"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"id": 9,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 기간 필터 적용",
|
||||
"action": "click_if_exists",
|
||||
@@ -80,7 +110,7 @@
|
||||
"expected": "필터 적용됨"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"id": 10,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 필터 결과 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -90,7 +120,7 @@
|
||||
"expected": "필터 동작 확인"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"id": 11,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 카드 사용내역 상세 보기",
|
||||
"action": "click_if_exists",
|
||||
@@ -100,7 +130,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"id": 12,
|
||||
"name": "상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
@@ -112,14 +142,14 @@
|
||||
"expected": "카드 사용 상세 정보 표시"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"id": 13,
|
||||
"name": "목록으로 돌아가기",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('목록'), a:has-text('목록'), [class*='back']",
|
||||
"expected": "목록 페이지로 복귀"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"id": 14,
|
||||
"name": "사용금액 합계 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -128,7 +158,7 @@
|
||||
"expected": "사용금액 합계 표시"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"id": 15,
|
||||
"name": "카드별 사용 현황 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -137,7 +167,7 @@
|
||||
"expected": "카드별 현황 표시"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"id": 16,
|
||||
"name": "엑셀 다운로드 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -146,7 +176,7 @@
|
||||
"expected": "엑셀 다운로드 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"id": 17,
|
||||
"name": "인쇄 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -155,13 +185,19 @@
|
||||
"expected": "인쇄 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"id": 18,
|
||||
"name": "페이지네이션 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"페이지 번호 표시"
|
||||
],
|
||||
"expected": "페이지네이션 표시"
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
@@ -180,13 +216,19 @@
|
||||
{
|
||||
"id": 3,
|
||||
"name": "검색/필터",
|
||||
"steps": [5, 6, 7],
|
||||
"steps": [
|
||||
5,
|
||||
6,
|
||||
7
|
||||
],
|
||||
"criteria": "기간 필터 동작"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"steps": [
|
||||
2
|
||||
],
|
||||
"criteria": "카드내역 목록, 카드 선택, 기간 필터 존재"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -49,6 +49,14 @@
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "URL 검증",
|
||||
"action": "verify_url",
|
||||
"expected": {
|
||||
"url_contains": "/accounting/vendors"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
@@ -59,7 +67,7 @@
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"id": 4,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -70,7 +78,7 @@
|
||||
"expected": "통계 카드 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"id": 5,
|
||||
"name": "거래처 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
@@ -83,7 +91,13 @@
|
||||
"expected": "거래처 테이블 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"id": 6,
|
||||
"name": "목록 필터 테스트",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const selects = document.querySelectorAll('select, [role=\"combobox\"], button[class*=\"select\"], button[class*=\"Select\"]');\n if (selects.length > 0) {\n return 'Filters found: ' + selects.length;\n }\n return 'No filter dropdowns (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 거래처 등록 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
@@ -93,7 +107,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"id": 8,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 거래처명 입력",
|
||||
"action": "click_if_exists",
|
||||
@@ -102,7 +116,7 @@
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"id": 9,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 거래처 구분 선택",
|
||||
"action": "click_if_exists",
|
||||
@@ -110,7 +124,7 @@
|
||||
"expected": "거래처 구분 선택"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"id": 10,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 필수 검증 #2: 거래처 저장",
|
||||
"action": "click_if_exists",
|
||||
@@ -124,7 +138,16 @@
|
||||
"expected": "거래처 등록 완료"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"id": 11,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 저장 완료 토스트 확인",
|
||||
"action": "verify_toast",
|
||||
"verify": {
|
||||
"contains": "등록|완료|성공|저장"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 등록된 거래처 검색",
|
||||
"action": "click_if_exists",
|
||||
@@ -133,7 +156,7 @@
|
||||
"submit": true
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"id": 13,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 등록된 거래처 목록 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -143,7 +166,7 @@
|
||||
"expected": "등록된 거래처 확인"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"id": 14,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 거래처 상세 조회",
|
||||
"action": "click_if_exists",
|
||||
@@ -154,7 +177,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"id": 15,
|
||||
"name": "상세 페이지 정보 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -165,7 +188,7 @@
|
||||
"expected": "상세 정보 표시"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"id": 16,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 모드 진입",
|
||||
"action": "click_if_exists",
|
||||
@@ -175,7 +198,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"id": 17,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 거래처 정보 수정",
|
||||
"action": "click_if_exists",
|
||||
@@ -184,7 +207,7 @@
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"id": 18,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 거래처 저장",
|
||||
"action": "click_if_exists",
|
||||
@@ -196,7 +219,16 @@
|
||||
"expected": "거래처 수정 완료"
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"id": 19,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 완료 토스트 확인",
|
||||
"action": "verify_toast",
|
||||
"verify": {
|
||||
"contains": "수정|완료|성공|저장"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 거래처 삭제",
|
||||
"action": "click_if_exists",
|
||||
@@ -206,7 +238,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"id": 21,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 삭제 확인",
|
||||
"action": "click_if_exists",
|
||||
@@ -218,7 +250,7 @@
|
||||
"expected": "거래처 삭제 완료"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"id": 22,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 삭제 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -226,6 +258,12 @@
|
||||
"E2E_TEST_회계거래처 목록에서 제거"
|
||||
],
|
||||
"expected": "거래처 삭제 반영"
|
||||
},
|
||||
{
|
||||
"id": 23,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
|
||||
@@ -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",
|
||||
@@ -39,11 +46,22 @@
|
||||
"level2": "입금관리",
|
||||
"expected": {
|
||||
"url_contains": "/accounting/deposits",
|
||||
"visible": ["입금관리", "입금"]
|
||||
"visible": [
|
||||
"입금관리",
|
||||
"입금"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "URL 검증",
|
||||
"action": "verify_url",
|
||||
"expected": {
|
||||
"url_contains": "/accounting/deposits"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
@@ -54,7 +72,13 @@
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"id": 4,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const cards = document.querySelectorAll('[class*=\"card\"], [class*=\"Card\"], [class*=\"stat\"], [class*=\"Stat\"], [class*=\"summary\"]');\n const texts = Array.from(cards).map(c => c.innerText?.substring(0, 30)).filter(Boolean);\n return texts.length > 0 ? 'Stats: ' + texts.length + ' cards found' : 'No stat cards (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "입금 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
@@ -67,7 +91,13 @@
|
||||
"expected": "입금 테이블 컬럼 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"id": 6,
|
||||
"name": "목록 필터 테스트",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const selects = document.querySelectorAll('select, [role=\"combobox\"], button[class*=\"select\"], button[class*=\"Select\"]');\n if (selects.length > 0) {\n return 'Filters found: ' + selects.length;\n }\n return 'No filter dropdowns (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "검색 기능 테스트",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[placeholder*='검색']",
|
||||
@@ -77,7 +107,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"id": 8,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 입금 등록 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
@@ -88,21 +118,41 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"id": 9,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 입금 정보 입력",
|
||||
"action": "fill_form",
|
||||
"fields": [
|
||||
{"name": "거래처", "type": "select", "value": "E2E_TEST_입금거래처"},
|
||||
{"name": "입금일", "type": "date", "value": "2026-02-03"},
|
||||
{"name": "금액", "type": "number", "value": "100000"},
|
||||
{"name": "입금방법", "type": "select", "value": "계좌이체"},
|
||||
{"name": "메모", "type": "text", "value": "E2E 자동화 테스트 입금_{timestamp}"}
|
||||
{
|
||||
"name": "거래처",
|
||||
"type": "select",
|
||||
"value": "E2E_TEST_입금거래처"
|
||||
},
|
||||
{
|
||||
"name": "입금일",
|
||||
"type": "date",
|
||||
"value": "2026-02-03"
|
||||
},
|
||||
{
|
||||
"name": "금액",
|
||||
"type": "number",
|
||||
"value": "100000"
|
||||
},
|
||||
{
|
||||
"name": "입금방법",
|
||||
"type": "select",
|
||||
"value": "계좌이체"
|
||||
},
|
||||
{
|
||||
"name": "메모",
|
||||
"type": "text",
|
||||
"value": "E2E 자동화 테스트 입금_{timestamp}"
|
||||
}
|
||||
],
|
||||
"note": "타임스탬프로 고유성 보장"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"id": 10,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 필수 검증 #2: 등록 저장",
|
||||
"action": "click_if_exists",
|
||||
@@ -116,36 +166,52 @@
|
||||
"expected": "입금 등록 완료"
|
||||
},
|
||||
{
|
||||
"id": "7-modal-close",
|
||||
"id": 11,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 저장 완료 토스트 확인",
|
||||
"action": "verify_toast",
|
||||
"verify": {
|
||||
"contains": "등록|완료|성공|저장"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 모달 닫기 확인",
|
||||
"action": "close_modal_if_open",
|
||||
"expected": "모달 닫힘"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"id": 13,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 등록 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"search": "E2E 자동화 테스트 입금",
|
||||
"expected": {
|
||||
"row_exists": true,
|
||||
"contains": ["E2E", "100,000"]
|
||||
"contains": [
|
||||
"E2E",
|
||||
"100,000"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"id": 14,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 입금 상세 페이지 진입",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:has-text('E2E')",
|
||||
"expected": {
|
||||
"url_contains": "/accounting/deposits/",
|
||||
"visible": ["입금 상세", "수정", "삭제"]
|
||||
"visible": [
|
||||
"입금 상세",
|
||||
"수정",
|
||||
"삭제"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"id": 15,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -157,7 +223,7 @@
|
||||
"expected": "입력한 데이터와 일치"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"id": 16,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 모드 진입",
|
||||
"action": "click_if_exists",
|
||||
@@ -168,7 +234,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"id": 17,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 금액 수정",
|
||||
"action": "click_if_exists",
|
||||
@@ -177,7 +243,7 @@
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"id": 18,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 메모 수정",
|
||||
"action": "click_if_exists",
|
||||
@@ -186,7 +252,7 @@
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"id": 19,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 필수 검증 #2: 수정 저장",
|
||||
"action": "click_if_exists",
|
||||
@@ -200,7 +266,16 @@
|
||||
"expected": "수정 완료"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"id": 20,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 완료 토스트 확인",
|
||||
"action": "verify_toast",
|
||||
"verify": {
|
||||
"contains": "수정|완료|성공|저장"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 결과 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -211,7 +286,7 @@
|
||||
"expected": "수정된 데이터 반영"
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"id": 22,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 삭제 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
@@ -222,7 +297,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"id": 23,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 필수 검증 #6: 삭제 확인",
|
||||
"action": "click_if_exists",
|
||||
@@ -235,7 +310,7 @@
|
||||
"expected": "삭제 완료 및 목록 복귀"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"id": 24,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 삭제 결과 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -244,6 +319,12 @@
|
||||
"row_exists": false,
|
||||
"message": "테스트 데이터가 목록에서 제거됨"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 25,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
@@ -277,19 +358,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 + 목록에서 제거"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -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,11 +34,22 @@
|
||||
"level2": "지출예상내역서",
|
||||
"expected": {
|
||||
"url_contains": "/accounting",
|
||||
"visible": ["지출", "예상"]
|
||||
"visible": [
|
||||
"지출",
|
||||
"예상"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "URL 검증",
|
||||
"action": "verify_url",
|
||||
"expected": {
|
||||
"url_contains": "/accounting/expected-expenses"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
@@ -42,7 +60,13 @@
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"id": 4,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const cards = document.querySelectorAll('[class*=\"card\"], [class*=\"Card\"], [class*=\"stat\"], [class*=\"Stat\"], [class*=\"summary\"]');\n const texts = Array.from(cards).map(c => c.innerText?.substring(0, 30)).filter(Boolean);\n return texts.length > 0 ? 'Stats: ' + texts.length + ' cards found' : 'No stat cards (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "지출예상 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
@@ -54,7 +78,13 @@
|
||||
"expected": "지출예상 테이블 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"id": 6,
|
||||
"name": "목록 필터 테스트",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const selects = document.querySelectorAll('select, [role=\"combobox\"], button[class*=\"select\"], button[class*=\"Select\"]');\n if (selects.length > 0) {\n return 'Filters found: ' + selects.length;\n }\n return 'No filter dropdowns (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "기간 선택 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -63,7 +93,7 @@
|
||||
"expected": "기간 선택 가능"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"id": 8,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 월 선택",
|
||||
"action": "click_if_exists",
|
||||
@@ -71,7 +101,7 @@
|
||||
"expected": "월 선택 열림"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"id": 9,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 조회 적용",
|
||||
"action": "click_if_exists",
|
||||
@@ -79,7 +109,7 @@
|
||||
"expected": "필터 적용됨"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"id": 10,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 필터 결과 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -89,7 +119,7 @@
|
||||
"expected": "필터 동작 확인"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"id": 11,
|
||||
"name": "지출 카테고리별 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -98,7 +128,7 @@
|
||||
"expected": "카테고리별 지출 표시"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"id": 12,
|
||||
"name": "합계 금액 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
@@ -107,7 +137,7 @@
|
||||
"expected": "합계 금액 표시"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"id": 13,
|
||||
"name": "일별 지출 예상 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -116,7 +146,7 @@
|
||||
"expected": "일별 지출 표시"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"id": 14,
|
||||
"name": "주요 지출 항목 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -125,7 +155,7 @@
|
||||
"expected": "주요 항목 표시"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"id": 15,
|
||||
"name": "인쇄 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -134,7 +164,7 @@
|
||||
"expected": "인쇄 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"id": 16,
|
||||
"name": "엑셀 다운로드 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -143,7 +173,7 @@
|
||||
"expected": "엑셀 다운로드 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"id": 17,
|
||||
"name": "PDF 내보내기 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -152,13 +182,19 @@
|
||||
"expected": "PDF 내보내기 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"id": 18,
|
||||
"name": "이전/다음 기간 네비게이션",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"이전/다음 기간 이동 가능"
|
||||
],
|
||||
"expected": "기간 네비게이션 표시"
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
@@ -177,13 +213,19 @@
|
||||
{
|
||||
"id": 3,
|
||||
"name": "검색/필터",
|
||||
"steps": [5, 6, 7],
|
||||
"steps": [
|
||||
5,
|
||||
6,
|
||||
7
|
||||
],
|
||||
"criteria": "기간 필터 동작"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"steps": [
|
||||
2
|
||||
],
|
||||
"criteria": "지출예상 목록, 기간 선택, 합계 표시 존재"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -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,11 +34,22 @@
|
||||
"level2": "결제내역",
|
||||
"expected": {
|
||||
"url_contains": "/payment",
|
||||
"visible": ["결제내역", "결제"]
|
||||
"visible": [
|
||||
"결제내역",
|
||||
"결제"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "URL 검증",
|
||||
"action": "verify_url",
|
||||
"expected": {
|
||||
"url_contains": "/payment-history"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
@@ -42,7 +60,13 @@
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"id": 4,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const cards = document.querySelectorAll('[class*=\"card\"], [class*=\"Card\"], [class*=\"stat\"], [class*=\"Stat\"], [class*=\"summary\"]');\n const texts = Array.from(cards).map(c => c.innerText?.substring(0, 30)).filter(Boolean);\n return texts.length > 0 ? 'Stats: ' + texts.length + ' cards found' : 'No stat cards (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "결제내역 페이지 구조 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -54,7 +78,7 @@
|
||||
"expected": "결제내역 조회 폼 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"id": 6,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 기간 필터 - 시작일",
|
||||
"action": "click_if_exists",
|
||||
@@ -63,7 +87,7 @@
|
||||
"expected": "시작일 입력"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"id": 7,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 기간 필터 - 종료일",
|
||||
"action": "click_if_exists",
|
||||
@@ -72,7 +96,7 @@
|
||||
"expected": "종료일 입력"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"id": 8,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 조회 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
@@ -83,7 +107,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"id": 9,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 결제 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
@@ -96,7 +120,13 @@
|
||||
"expected": "결제 테이블 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"id": 10,
|
||||
"name": "목록 필터 테스트",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const selects = document.querySelectorAll('select, [role=\"combobox\"], button[class*=\"select\"], button[class*=\"Select\"]');\n if (selects.length > 0) {\n return 'Filters found: ' + selects.length;\n }\n return 'No filter dropdowns (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 결제 데이터 표시 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -107,7 +137,7 @@
|
||||
"expected": "결제 데이터 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"id": 12,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 결제방법 필터 테스트",
|
||||
"action": "click_if_exists",
|
||||
@@ -115,7 +145,7 @@
|
||||
"expected": "결제방법 필터 옵션 표시"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"id": 13,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 상태 필터 테스트",
|
||||
"action": "verify_elements",
|
||||
@@ -125,7 +155,7 @@
|
||||
"expected": "상태 필터 기능 확인"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"id": 14,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 결제 상세 조회",
|
||||
"action": "click_if_exists",
|
||||
@@ -135,7 +165,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"id": 15,
|
||||
"name": "결제 상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
@@ -147,14 +177,14 @@
|
||||
"expected": "결제 상세 정보 표시"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"id": 16,
|
||||
"name": "목록으로 돌아가기",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('목록'), button:has-text('뒤로'), [class*='back']",
|
||||
"expected": "목록 페이지로 복귀"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"id": 17,
|
||||
"name": "필수 검증 #1: 엑셀 다운로드",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('엑셀'), button:has-text('Excel'), button:has-text('다운로드')",
|
||||
@@ -165,13 +195,19 @@
|
||||
"expected": "엑셀 파일 다운로드"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"id": 18,
|
||||
"name": "합계 금액 표시 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"총 결제금액 합계 표시"
|
||||
],
|
||||
"expected": "합계 영역 표시"
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
@@ -195,13 +231,17 @@
|
||||
{
|
||||
"id": 1,
|
||||
"name": "엑셀 다운로드",
|
||||
"steps": [14],
|
||||
"steps": [
|
||||
14
|
||||
],
|
||||
"criteria": "API 호출 + 파일 다운로드"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"steps": [
|
||||
2
|
||||
],
|
||||
"criteria": "결제 내역 목록, 기간 필터, 검색 기능 존재"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -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": "/accounting",
|
||||
"visible": ["매입관리", "매입"]
|
||||
"visible": [
|
||||
"매입관리",
|
||||
"매입"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -43,6 +53,12 @@
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const cards = document.querySelectorAll('[class*=\"card\"], [class*=\"Card\"], [class*=\"stat\"], [class*=\"Stat\"], [class*=\"summary\"]');\n const texts = Array.from(cards).map(c => c.innerText?.substring(0, 30)).filter(Boolean);\n return texts.length > 0 ? 'Stats: ' + texts.length + ' cards found' : 'No stat cards (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "매입 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
@@ -55,7 +71,13 @@
|
||||
"expected": "매입 테이블 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"id": 5,
|
||||
"name": "목록 필터 테스트",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const selects = document.querySelectorAll('select, [role=\"combobox\"], button[class*=\"select\"], button[class*=\"Select\"]');\n if (selects.length > 0) {\n return 'Filters found: ' + selects.length;\n }\n return 'No filter dropdowns (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "매입 통계 카드 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -66,7 +88,7 @@
|
||||
"expected": "통계 카드 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"id": 7,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 기간 필터 - 시작일",
|
||||
"action": "click_if_exists",
|
||||
@@ -74,7 +96,7 @@
|
||||
"expected": "날짜 선택 열림"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"id": 8,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 기간 필터 적용",
|
||||
"action": "click_if_exists",
|
||||
@@ -82,7 +104,7 @@
|
||||
"expected": "필터 적용됨"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"id": 9,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 필터 결과 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -92,7 +114,7 @@
|
||||
"expected": "필터 동작 확인"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"id": 10,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 거래처별 필터",
|
||||
"action": "click_if_exists",
|
||||
@@ -100,7 +122,7 @@
|
||||
"expected": "거래처 필터 가능"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"id": 11,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 매입 상세 보기",
|
||||
"action": "click_if_exists",
|
||||
@@ -110,7 +132,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"id": 12,
|
||||
"name": "상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
@@ -121,14 +143,14 @@
|
||||
"expected": "매입 상세 정보 표시"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"id": 13,
|
||||
"name": "목록으로 돌아가기",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('목록'), a:has-text('목록'), [class*='back']",
|
||||
"expected": "목록 페이지로 복귀"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"id": 14,
|
||||
"name": "매입 합계 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -137,7 +159,7 @@
|
||||
"expected": "매입 합계 표시"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"id": 15,
|
||||
"name": "엑셀 다운로드 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -146,7 +168,7 @@
|
||||
"expected": "엑셀 다운로드 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"id": 16,
|
||||
"name": "인쇄 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -155,13 +177,19 @@
|
||||
"expected": "인쇄 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"id": 17,
|
||||
"name": "페이지네이션 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"페이지 번호 표시"
|
||||
],
|
||||
"expected": "페이지네이션 표시"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
@@ -180,13 +208,20 @@
|
||||
{
|
||||
"id": 3,
|
||||
"name": "검색/필터",
|
||||
"steps": [5, 6, 7, 8],
|
||||
"steps": [
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8
|
||||
],
|
||||
"criteria": "기간 필터 + 거래처 필터 동작"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"steps": [
|
||||
2
|
||||
],
|
||||
"criteria": "매입 목록, 기간 필터, 합계 표시 존재"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -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",
|
||||
@@ -32,11 +39,22 @@
|
||||
"level2": "미수금현황",
|
||||
"expected": {
|
||||
"url_contains": "/accounting/receivables",
|
||||
"visible": ["미수금현황", "미수금"]
|
||||
"visible": [
|
||||
"미수금현황",
|
||||
"미수금"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "URL 검증",
|
||||
"action": "verify_url",
|
||||
"expected": {
|
||||
"url_contains": "/accounting/receivables-status"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
@@ -47,7 +65,13 @@
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"id": 4,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const cards = document.querySelectorAll('[class*=\"card\"], [class*=\"Card\"], [class*=\"stat\"], [class*=\"Stat\"], [class*=\"summary\"]');\n const texts = Array.from(cards).map(c => c.innerText?.substring(0, 30)).filter(Boolean);\n return texts.length > 0 ? 'Stats: ' + texts.length + ' cards found' : 'No stat cards (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "미수금 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
@@ -60,7 +84,13 @@
|
||||
"expected": "미수금 테이블 컬럼 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"id": 6,
|
||||
"name": "목록 필터 테스트",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const selects = document.querySelectorAll('select, [role=\"combobox\"], button[class*=\"select\"], button[class*=\"Select\"]');\n if (selects.length > 0) {\n return 'Filters found: ' + selects.length;\n }\n return 'No filter dropdowns (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -71,20 +101,29 @@
|
||||
"expected": "미수금 통계 카드 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"id": 8,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 기간 필터 적용",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "input[type='date']:first-of-type, input[placeholder*='시작'], input[name*='start']" },
|
||||
{ "type": "click_if_exists", "target": "input[type='date']:last-of-type, input[placeholder*='종료'], input[name*='end']" },
|
||||
{ "type": "wait", "duration": 500 }
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "input[type='date']:first-of-type, input[placeholder*='시작'], input[name*='start']"
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "input[type='date']:last-of-type, input[placeholder*='종료'], input[name*='end']"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 500
|
||||
}
|
||||
],
|
||||
"expected": {
|
||||
"filter_applied": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"id": 9,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 필터 결과 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -94,7 +133,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"id": 10,
|
||||
"phase": "SEARCH",
|
||||
"name": "[SEARCH] 거래처 검색",
|
||||
"action": "click_if_exists",
|
||||
@@ -105,7 +144,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"id": 11,
|
||||
"phase": "SEARCH",
|
||||
"name": "[SEARCH] 검색 결과 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -116,18 +155,22 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"id": 12,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 미수금 상세 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:first-child",
|
||||
"expected": {
|
||||
"detail_modal_or_page": true,
|
||||
"visible": ["거래처", "미수금액", "상세"]
|
||||
"visible": [
|
||||
"거래처",
|
||||
"미수금액",
|
||||
"상세"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"id": 13,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -139,7 +182,7 @@
|
||||
"expected": "미수금 상세 정보 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"id": 14,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 목록으로 복귀",
|
||||
"action": "click_if_exists",
|
||||
@@ -149,7 +192,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"id": 15,
|
||||
"phase": "EXPORT",
|
||||
"name": "[EXPORT] 엑셀 다운로드 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
@@ -159,7 +202,7 @@
|
||||
"expected": "다운로드 기능 존재"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"id": 16,
|
||||
"phase": "EXPORT",
|
||||
"name": "[EXPORT] 필수 검증 #1: 엑셀 다운로드",
|
||||
"action": "click_if_exists",
|
||||
@@ -172,7 +215,7 @@
|
||||
"expected": "엑셀 파일 다운로드"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"id": 17,
|
||||
"phase": "SORT",
|
||||
"name": "[SORT] 컬럼 정렬 테스트",
|
||||
"action": "click_if_exists",
|
||||
@@ -183,7 +226,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"id": 18,
|
||||
"name": "연체 현황 탭 확인",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('연체'), [role='tab']:has-text('연체')",
|
||||
@@ -191,6 +234,12 @@
|
||||
"tab_active": true,
|
||||
"filtered_data": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
@@ -219,19 +268,28 @@
|
||||
{
|
||||
"id": 1,
|
||||
"name": "파일 다운로드",
|
||||
"steps": [13],
|
||||
"steps": [
|
||||
13
|
||||
],
|
||||
"criteria": "엑셀 파일 다운로드 동작"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "검색/필터",
|
||||
"steps": [5, 6, 7, 8],
|
||||
"steps": [
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8
|
||||
],
|
||||
"criteria": "기간 필터 및 검색 기능"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"steps": [
|
||||
2
|
||||
],
|
||||
"criteria": "미수금 목록, 필터, 다운로드 버튼 존재"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -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": "/accounting",
|
||||
"visible": ["매출관리", "매출"]
|
||||
"visible": [
|
||||
"매출관리",
|
||||
"매출"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -43,6 +53,12 @@
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const cards = document.querySelectorAll('[class*=\"card\"], [class*=\"Card\"], [class*=\"stat\"], [class*=\"Stat\"], [class*=\"summary\"]');\n const texts = Array.from(cards).map(c => c.innerText?.substring(0, 30)).filter(Boolean);\n return texts.length > 0 ? 'Stats: ' + texts.length + ' cards found' : 'No stat cards (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "매출 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
@@ -55,7 +71,13 @@
|
||||
"expected": "매출 테이블 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"id": 5,
|
||||
"name": "목록 필터 테스트",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const selects = document.querySelectorAll('select, [role=\"combobox\"], button[class*=\"select\"], button[class*=\"Select\"]');\n if (selects.length > 0) {\n return 'Filters found: ' + selects.length;\n }\n return 'No filter dropdowns (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "매출 통계 카드 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -66,7 +88,7 @@
|
||||
"expected": "통계 카드 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"id": 7,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 기간 필터 - 시작일",
|
||||
"action": "click_if_exists",
|
||||
@@ -74,7 +96,7 @@
|
||||
"expected": "날짜 선택 열림"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"id": 8,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 기간 필터 적용",
|
||||
"action": "click_if_exists",
|
||||
@@ -82,7 +104,7 @@
|
||||
"expected": "필터 적용됨"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"id": 9,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 필터 결과 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -92,7 +114,7 @@
|
||||
"expected": "필터 동작 확인"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"id": 10,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 거래처별 필터",
|
||||
"action": "click_if_exists",
|
||||
@@ -100,7 +122,7 @@
|
||||
"expected": "거래처 필터 가능"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"id": 11,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 매출 상세 보기",
|
||||
"action": "click_if_exists",
|
||||
@@ -110,7 +132,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"id": 12,
|
||||
"name": "상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
@@ -121,14 +143,14 @@
|
||||
"expected": "매출 상세 정보 표시"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"id": 13,
|
||||
"name": "목록으로 돌아가기",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('목록'), a:has-text('목록'), [class*='back']",
|
||||
"expected": "목록 페이지로 복귀"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"id": 14,
|
||||
"name": "매출 합계 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -137,7 +159,7 @@
|
||||
"expected": "매출 합계 표시"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"id": 15,
|
||||
"name": "엑셀 다운로드 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -146,7 +168,7 @@
|
||||
"expected": "엑셀 다운로드 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"id": 16,
|
||||
"name": "인쇄 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -155,13 +177,19 @@
|
||||
"expected": "인쇄 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"id": 17,
|
||||
"name": "페이지네이션 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"페이지 번호 표시"
|
||||
],
|
||||
"expected": "페이지네이션 표시"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
@@ -180,13 +208,20 @@
|
||||
{
|
||||
"id": 3,
|
||||
"name": "검색/필터",
|
||||
"steps": [5, 6, 7, 8],
|
||||
"steps": [
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8
|
||||
],
|
||||
"criteria": "기간 필터 + 거래처 필터 동작"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"steps": [
|
||||
2
|
||||
],
|
||||
"criteria": "매출 목록, 기간 필터, 합계 표시 존재"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -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",
|
||||
@@ -39,11 +46,22 @@
|
||||
"level2": "출금관리",
|
||||
"expected": {
|
||||
"url_contains": "/accounting/withdrawals",
|
||||
"visible": ["출금관리", "출금"]
|
||||
"visible": [
|
||||
"출금관리",
|
||||
"출금"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "URL 검증",
|
||||
"action": "verify_url",
|
||||
"expected": {
|
||||
"url_contains": "/accounting/withdrawals"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
@@ -54,7 +72,13 @@
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"id": 4,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const cards = document.querySelectorAll('[class*=\"card\"], [class*=\"Card\"], [class*=\"stat\"], [class*=\"Stat\"], [class*=\"summary\"]');\n const texts = Array.from(cards).map(c => c.innerText?.substring(0, 30)).filter(Boolean);\n return texts.length > 0 ? 'Stats: ' + texts.length + ' cards found' : 'No stat cards (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "출금 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
@@ -67,7 +91,13 @@
|
||||
"expected": "출금 테이블 컬럼 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"id": 6,
|
||||
"name": "목록 필터 테스트",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const selects = document.querySelectorAll('select, [role=\"combobox\"], button[class*=\"select\"], button[class*=\"Select\"]');\n if (selects.length > 0) {\n return 'Filters found: ' + selects.length;\n }\n return 'No filter dropdowns (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "검색 기능 테스트",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[placeholder*='검색']",
|
||||
@@ -77,7 +107,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"id": 8,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 출금 등록 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
@@ -88,21 +118,41 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"id": 9,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 출금 정보 입력",
|
||||
"action": "fill_form",
|
||||
"fields": [
|
||||
{"name": "거래처", "type": "select", "value": "E2E_TEST_출금거래처"},
|
||||
{"name": "출금일", "type": "date", "value": "2026-02-03"},
|
||||
{"name": "금액", "type": "number", "value": "50000"},
|
||||
{"name": "출금방법", "type": "select", "value": "계좌이체"},
|
||||
{"name": "메모", "type": "text", "value": "E2E 자동화 테스트 출금_{timestamp}"}
|
||||
{
|
||||
"name": "거래처",
|
||||
"type": "select",
|
||||
"value": "E2E_TEST_출금거래처"
|
||||
},
|
||||
{
|
||||
"name": "출금일",
|
||||
"type": "date",
|
||||
"value": "2026-02-03"
|
||||
},
|
||||
{
|
||||
"name": "금액",
|
||||
"type": "number",
|
||||
"value": "50000"
|
||||
},
|
||||
{
|
||||
"name": "출금방법",
|
||||
"type": "select",
|
||||
"value": "계좌이체"
|
||||
},
|
||||
{
|
||||
"name": "메모",
|
||||
"type": "text",
|
||||
"value": "E2E 자동화 테스트 출금_{timestamp}"
|
||||
}
|
||||
],
|
||||
"note": "타임스탬프로 고유성 보장"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"id": 10,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 필수 검증 #2: 등록 저장",
|
||||
"action": "click_if_exists",
|
||||
@@ -116,36 +166,52 @@
|
||||
"expected": "출금 등록 완료"
|
||||
},
|
||||
{
|
||||
"id": "7-modal-close",
|
||||
"id": 11,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 저장 완료 토스트 확인",
|
||||
"action": "verify_toast",
|
||||
"verify": {
|
||||
"contains": "등록|완료|성공|저장"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 모달 닫기 확인",
|
||||
"action": "close_modal_if_open",
|
||||
"expected": "모달 닫힘"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"id": 13,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 등록 결과 확인",
|
||||
"action": "verify_detail",
|
||||
"search": "E2E 자동화 테스트 출금",
|
||||
"expected": {
|
||||
"row_exists": true,
|
||||
"contains": ["E2E", "50,000"]
|
||||
"contains": [
|
||||
"E2E",
|
||||
"50,000"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"id": 14,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 출금 상세 페이지 진입",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:has-text('E2E')",
|
||||
"expected": {
|
||||
"url_contains": "/accounting/withdrawals/",
|
||||
"visible": ["출금 상세", "수정", "삭제"]
|
||||
"visible": [
|
||||
"출금 상세",
|
||||
"수정",
|
||||
"삭제"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"id": 15,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -157,7 +223,7 @@
|
||||
"expected": "입력한 데이터와 일치"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"id": 16,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 모드 진입",
|
||||
"action": "click_if_exists",
|
||||
@@ -168,7 +234,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"id": 17,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 금액 수정",
|
||||
"action": "click_if_exists",
|
||||
@@ -177,7 +243,7 @@
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"id": 18,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 메모 수정",
|
||||
"action": "click_if_exists",
|
||||
@@ -186,7 +252,7 @@
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"id": 19,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 필수 검증 #2: 수정 저장",
|
||||
"action": "click_if_exists",
|
||||
@@ -200,7 +266,16 @@
|
||||
"expected": "수정 완료"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"id": 20,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 완료 토스트 확인",
|
||||
"action": "verify_toast",
|
||||
"verify": {
|
||||
"contains": "수정|완료|성공|저장"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 결과 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -211,7 +286,7 @@
|
||||
"expected": "수정된 데이터 반영"
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"id": 22,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 삭제 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
@@ -222,7 +297,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"id": 23,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 필수 검증 #6: 삭제 확인",
|
||||
"action": "click_if_exists",
|
||||
@@ -235,7 +310,7 @@
|
||||
"expected": "삭제 완료 및 목록 복귀"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"id": 24,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 삭제 결과 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -244,6 +319,12 @@
|
||||
"row_exists": false,
|
||||
"message": "테스트 데이터가 목록에서 제거됨"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 25,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
@@ -277,19 +358,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 + 목록에서 제거"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"id": 0,
|
||||
"id": 1,
|
||||
"name": "사이드바 메뉴 전체 펼치기",
|
||||
"description": "모두 펼치기 버튼을 클릭하여 전체 메뉴를 펼친 후 메뉴 탐색 준비",
|
||||
"actions": [
|
||||
@@ -92,7 +92,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"id": 2,
|
||||
"name": "1차 메뉴 찾기: 결재관리 (스크롤 포함)",
|
||||
"description": "사이드바를 스크롤하며 '결재관리' 메뉴를 찾아 클릭",
|
||||
"actions": [
|
||||
@@ -139,7 +139,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"id": 3,
|
||||
"name": "2차 메뉴 찾기: 결재함 (스크롤 포함)",
|
||||
"description": "서브메뉴에서 '결재함'을 찾아 클릭",
|
||||
"actions": [
|
||||
@@ -181,7 +181,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"id": 4,
|
||||
"name": "404 에러 감지 및 대체 경로 시도",
|
||||
"description": "페이지 로드 후 404 에러 여부 확인, 404시 대체 경로 탐색",
|
||||
"actions": [
|
||||
@@ -231,7 +231,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"id": 5,
|
||||
"name": "페이지 정상 로드 확인",
|
||||
"description": "결재함 페이지가 정상적으로 로드되었는지 확인",
|
||||
"actions": [
|
||||
@@ -269,7 +269,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"id": 6,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "verify_element",
|
||||
"target": "[class*='card'], [class*='stat']",
|
||||
@@ -281,7 +281,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"id": 7,
|
||||
"name": "탭 구조 확인",
|
||||
"action": "verify_element",
|
||||
"target": "[role='tab'], button[role='tab']",
|
||||
@@ -293,7 +293,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"id": 8,
|
||||
"name": "테이블 데이터 확인",
|
||||
"action": "verify_table",
|
||||
"target": "table",
|
||||
@@ -304,7 +304,13 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"id": 9,
|
||||
"name": "목록 필터 테스트",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const selects = document.querySelectorAll('select, [role=\"combobox\"], button[class*=\"select\"], button[class*=\"Select\"]');\n if (selects.length > 0) {\n return 'Filters found: ' + selects.length;\n }\n return 'No filter dropdowns (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "⚠️ 필수 검증: 결재 문서 상세 보기",
|
||||
"description": "테이블에서 결재 문서 클릭하여 상세 모달/페이지 확인",
|
||||
"actions": [
|
||||
@@ -345,7 +351,7 @@
|
||||
"note": "결재 문서가 없으면 데이터 생성 또는 SKIP"
|
||||
},
|
||||
{
|
||||
"id": "8-pdf-1",
|
||||
"id": 11,
|
||||
"name": "⚠️ 필수 검증: PDF 다운로드 전 모달 스크린샷",
|
||||
"description": "PDF 생성 전 모달 상태를 스크린샷으로 캡처하여 CSS 문제 감지용 기준 이미지 확보",
|
||||
"prerequisite": "step-8의 문서 상세 모달이 열려있는 상태에서 실행",
|
||||
@@ -365,7 +371,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "8-pdf-2",
|
||||
"id": 12,
|
||||
"name": "⚠️ 필수 검증: PDF 다운로드 실행 및 파일 보관",
|
||||
"description": "PDF 다운로드 후 파일을 지정 폴더에 보관하여 수동 검증 가능하게 함",
|
||||
"actions": [
|
||||
@@ -414,7 +420,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "8-pdf-3",
|
||||
"id": 13,
|
||||
"name": "⚠️ PDF 파일 유효성 검증",
|
||||
"description": "다운로드된 PDF 파일의 기본 유효성 검사",
|
||||
"actions": [
|
||||
@@ -434,7 +440,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "8-pdf-4",
|
||||
"id": 14,
|
||||
"name": "📋 PDF 스타일 수동 확인 체크리스트",
|
||||
"type": "manualVerification",
|
||||
"description": "개발자가 다운로드된 PDF를 열어 시각적으로 확인해야 하는 항목",
|
||||
@@ -500,7 +506,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"id": 15,
|
||||
"name": "⚠️ 필수 검증 #4: 결재 승인 실제 수행",
|
||||
"description": "미결재 문서에 대해 실제 승인 처리 수행",
|
||||
"actions": [
|
||||
@@ -533,7 +539,7 @@
|
||||
"note": "⚠️ 버튼 존재만 확인하면 불완전! 실제 승인까지 검증 필수!"
|
||||
},
|
||||
{
|
||||
"id": "9-1",
|
||||
"id": 16,
|
||||
"name": "결재 승인 결과 확인",
|
||||
"description": "승인 후 결재완료 탭에서 해당 문서 확인",
|
||||
"actions": [
|
||||
@@ -552,7 +558,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"id": 17,
|
||||
"name": "⚠️ 필수 검증 #4: 결재 반려 실제 수행",
|
||||
"description": "미결재 문서에 대해 실제 반려 처리 수행",
|
||||
"actions": [
|
||||
@@ -603,7 +609,7 @@
|
||||
"note": "⚠️ 반려 버튼 존재만 확인하면 불완전! 실제 반려까지 검증 필수!"
|
||||
},
|
||||
{
|
||||
"id": "10-1",
|
||||
"id": 18,
|
||||
"name": "결재 반려 결과 확인",
|
||||
"description": "반려 후 결재반려 탭에서 해당 문서 확인",
|
||||
"actions": [
|
||||
@@ -623,7 +629,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"id": 19,
|
||||
"name": "검색 기능 테스트",
|
||||
"description": "검색 필터로 결재 문서 검색",
|
||||
"actions": [
|
||||
@@ -644,6 +650,12 @@
|
||||
"searchApplied": true,
|
||||
"filteredResults": "검색어에 맞는 결과 표시"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body"
|
||||
}
|
||||
],
|
||||
"mandatoryVerifications": {
|
||||
|
||||
@@ -3,16 +3,27 @@
|
||||
"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",
|
||||
"url": "/hr/attendance",
|
||||
|
||||
"navigation": {
|
||||
"targetUrl": "/hr/attendance",
|
||||
"urlPattern": "/hr/attendance|/ko/hr/attendance",
|
||||
"menuHints": ["근태현황", "근태 현황", "출퇴근", "인사관리"]
|
||||
"menuHints": [
|
||||
"근태현황",
|
||||
"근태 현황",
|
||||
"출퇴근",
|
||||
"인사관리"
|
||||
]
|
||||
},
|
||||
"menuNavigation": {
|
||||
"level1": "인사관리",
|
||||
@@ -26,8 +37,21 @@
|
||||
"description": "사이드바를 스크롤하며 메뉴를 찾고 클릭하여 404를 방지",
|
||||
"level1": "인사관리",
|
||||
"level2": "근태현황",
|
||||
"alternativeLevel1Names": ["인사관리", "인사 관리", "HR", "Human Resource", "HR관리"],
|
||||
"alternativeLevel2Names": ["근태현황", "근태 현황", "출퇴근", "Attendance", "출퇴근현황", "근태관리"],
|
||||
"alternativeLevel1Names": [
|
||||
"인사관리",
|
||||
"인사 관리",
|
||||
"HR",
|
||||
"Human Resource",
|
||||
"HR관리"
|
||||
],
|
||||
"alternativeLevel2Names": [
|
||||
"근태현황",
|
||||
"근태 현황",
|
||||
"출퇴근",
|
||||
"Attendance",
|
||||
"출퇴근현황",
|
||||
"근태관리"
|
||||
],
|
||||
"fallbackUrls": [
|
||||
"/hr/attendance",
|
||||
"/ko/hr/attendance",
|
||||
@@ -43,15 +67,18 @@
|
||||
"scrollDelay": 300
|
||||
}
|
||||
},
|
||||
|
||||
"timeout": 120000,
|
||||
"tags": ["hr", "attendance", "geolocation", "checkin", "checkout"],
|
||||
|
||||
"tags": [
|
||||
"hr",
|
||||
"attendance",
|
||||
"geolocation",
|
||||
"checkin",
|
||||
"checkout"
|
||||
],
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
|
||||
"browserConfig": {
|
||||
"permissions": {
|
||||
"geolocation": {
|
||||
@@ -70,14 +97,17 @@
|
||||
"latitude": 37.557358,
|
||||
"longitude": 126.864414
|
||||
},
|
||||
"permissions": ["geolocation"]
|
||||
"permissions": [
|
||||
"geolocation"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
"preTestSetup": {
|
||||
"description": "테스트 시작 전 Playwright 브라우저 컨텍스트에서 위치 권한 설정",
|
||||
"playwright": {
|
||||
"grantPermissions": ["geolocation"],
|
||||
"grantPermissions": [
|
||||
"geolocation"
|
||||
],
|
||||
"setGeolocation": {
|
||||
"latitude": 37.557358,
|
||||
"longitude": 126.864414,
|
||||
@@ -91,10 +121,9 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
"steps": [
|
||||
{
|
||||
"id": "step-0",
|
||||
"id": 1,
|
||||
"name": "🔐 Geolocation API 모킹 (권한 팝업 방지)",
|
||||
"description": "페이지 로드 직후 Geolocation API를 모킹하여 브라우저 권한 팝업이 나타나지 않도록 함",
|
||||
"executeBeforeNavigation": false,
|
||||
@@ -105,22 +134,34 @@
|
||||
"script": "(() => { const mockPosition = { coords: { latitude: 37.557358, longitude: 126.864414, accuracy: 100, altitude: null, altitudeAccuracy: null, heading: null, speed: null }, timestamp: Date.now() }; const mockGeolocation = { getCurrentPosition: (success, error, options) => { console.log('[E2E] Geolocation.getCurrentPosition - 모킹된 위치 반환'); setTimeout(() => success(mockPosition), 50); }, watchPosition: (success, error, options) => { console.log('[E2E] Geolocation.watchPosition - 모킹된 위치 반환'); setTimeout(() => success(mockPosition), 50); return 1; }, clearWatch: (id) => {} }; Object.defineProperty(navigator, 'geolocation', { value: mockGeolocation, writable: false, configurable: true }); console.log('[E2E] Geolocation API 모킹 완료 - 서울 영등포구 좌표'); return { success: true, coords: mockPosition.coords }; })()",
|
||||
"description": "Geolocation API 모킹 (서울 영등포구 좌표: 37.557358, 126.864414)"
|
||||
},
|
||||
{ "type": "wait", "duration": 300, "description": "모킹 적용 대기" }
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 300,
|
||||
"description": "모킹 적용 대기"
|
||||
}
|
||||
],
|
||||
"note": "Geolocation API를 모킹하면 브라우저가 위치 권한을 요청하지 않음"
|
||||
},
|
||||
{
|
||||
"id": "step-0-1",
|
||||
"id": 2,
|
||||
"name": "🗺️ 브라우저 위치 권한 팝업 클릭 (좌측 상단)",
|
||||
"description": "Chrome 브라우저 좌측 상단에 나타나는 '사이트에 있는 동안 허용' 팝업 클릭",
|
||||
"actions": [
|
||||
{ "type": "wait", "duration": 1500, "description": "위치 권한 팝업 표시 대기" },
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 1500,
|
||||
"description": "위치 권한 팝업 표시 대기"
|
||||
},
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "(async function() { const permissionSelectors = [ '[class*=\"permission\"][class*=\"allow\"]', '[class*=\"infobar\"] button', '[aria-label*=\"허용\"]', '[aria-label*=\"Allow\"]', 'button:has-text(\"사이트에 있는 동안 허용\")', 'button:has-text(\"허용\")', 'button:has-text(\"Allow\")', '[data-testid*=\"permission\"]', '.permission-prompt button', '[class*=\"PermissionPrompt\"] button' ]; for (const sel of permissionSelectors) { try { const btn = document.querySelector(sel); if (btn && btn.offsetParent !== null) { btn.click(); console.log('[E2E] 위치 권한 팝업 클릭 성공:', sel); await new Promise(r => setTimeout(r, 500)); return { clicked: true, selector: sel }; } } catch(e) {} } const allButtons = Array.from(document.querySelectorAll('button, [role=\"button\"]')); const allowBtn = allButtons.find(b => { const text = b.innerText || b.textContent || ''; return text.includes('사이트에 있는 동안 허용') || text.includes('허용') || text.includes('Allow'); }); if (allowBtn && allowBtn.offsetParent !== null) { allowBtn.click(); console.log('[E2E] 위치 권한 팝업 텍스트 검색으로 클릭'); return { clicked: true, method: 'textSearch' }; } console.log('[E2E] 위치 권한 팝업 없음 (이미 허용되었거나 모킹으로 우회됨)'); return { clicked: false, reason: 'no_popup_found' }; })()",
|
||||
"description": "좌측 상단 권한 팝업 찾아서 클릭"
|
||||
},
|
||||
{ "type": "wait", "duration": 500, "description": "권한 설정 적용 대기" }
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 500,
|
||||
"description": "권한 설정 적용 대기"
|
||||
}
|
||||
],
|
||||
"errorHandling": {
|
||||
"onTimeout": "continue",
|
||||
@@ -129,7 +170,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-0-2",
|
||||
"id": 3,
|
||||
"name": "📂 사이드바 메뉴 전체 펼치기",
|
||||
"description": "모두 펼치기 버튼을 클릭하여 전체 메뉴 펼침",
|
||||
"actions": [
|
||||
@@ -137,35 +178,63 @@
|
||||
"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": "screenshot", "name": "after_permission_grant_and_menu_expanded" }
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 2000
|
||||
},
|
||||
{
|
||||
"type": "screenshot",
|
||||
"name": "after_permission_grant_and_menu_expanded"
|
||||
}
|
||||
],
|
||||
"verification": [
|
||||
"사이드바 메뉴가 펼쳐졌는지 확인"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"id": 4,
|
||||
"name": "1차 메뉴 찾기: 인사관리 (스크롤 포함)",
|
||||
"description": "사이드바를 스크롤하며 '인사관리' 메뉴를 찾아 클릭",
|
||||
"actions": [
|
||||
{
|
||||
"type": "scrollAndFind",
|
||||
"target": "인사관리",
|
||||
"alternativeTexts": ["인사관리", "인사 관리", "HR", "Human Resource"],
|
||||
"alternativeTexts": [
|
||||
"인사관리",
|
||||
"인사 관리",
|
||||
"HR",
|
||||
"Human Resource"
|
||||
],
|
||||
"scrollContainer": "sidebar",
|
||||
"maxAttempts": 10,
|
||||
"description": "스크롤하며 인사관리 메뉴 찾기"
|
||||
},
|
||||
{ "type": "wait", "duration": 300 },
|
||||
{ "type": "click_if_exists", "target": "인사관리", "description": "인사관리 메뉴 클릭" },
|
||||
{ "type": "wait", "duration": 500, "description": "서브메뉴 펼쳐지기 대기" },
|
||||
{ "type": "screenshot", "name": "hr_menu_expanded" }
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 300
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "인사관리",
|
||||
"description": "인사관리 메뉴 클릭"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 500,
|
||||
"description": "서브메뉴 펼쳐지기 대기"
|
||||
},
|
||||
{
|
||||
"type": "screenshot",
|
||||
"name": "hr_menu_expanded"
|
||||
}
|
||||
],
|
||||
"verification": [
|
||||
"인사관리 메뉴가 클릭되었는지 확인",
|
||||
@@ -178,22 +247,41 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"id": 5,
|
||||
"name": "2차 메뉴 찾기: 근태현황 (스크롤 포함)",
|
||||
"description": "서브메뉴에서 '근태현황'을 찾아 클릭",
|
||||
"actions": [
|
||||
{
|
||||
"type": "scrollAndFind",
|
||||
"target": "근태현황",
|
||||
"alternativeTexts": ["근태현황", "근태 현황", "출퇴근", "Attendance"],
|
||||
"alternativeTexts": [
|
||||
"근태현황",
|
||||
"근태 현황",
|
||||
"출퇴근",
|
||||
"Attendance"
|
||||
],
|
||||
"scrollContainer": "submenu",
|
||||
"maxAttempts": 5,
|
||||
"description": "서브메뉴에서 근태현황 찾기"
|
||||
},
|
||||
{ "type": "wait", "duration": 200 },
|
||||
{ "type": "click_if_exists", "target": "근태현황", "description": "근태현황 메뉴 클릭" },
|
||||
{ "type": "wait", "target": "페이지 로드 완료", "timeout": 10000 },
|
||||
{ "type": "screenshot", "name": "attendance_page" }
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 200
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "근태현황",
|
||||
"description": "근태현황 메뉴 클릭"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"target": "페이지 로드 완료",
|
||||
"timeout": 10000
|
||||
},
|
||||
{
|
||||
"type": "screenshot",
|
||||
"name": "attendance_page"
|
||||
}
|
||||
],
|
||||
"verification": [
|
||||
"근태현황 메뉴 클릭 성공",
|
||||
@@ -201,18 +289,27 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"id": 6,
|
||||
"name": "404 에러 감지 및 대체 경로 시도",
|
||||
"description": "페이지 로드 후 404 에러 여부 확인, 404시 대체 경로 탐색",
|
||||
"actions": [
|
||||
{ "type": "wait", "duration": 1000 },
|
||||
{ "type": "checkFor404", "indicators": [
|
||||
"페이지를 찾을 수 없습니다",
|
||||
"404",
|
||||
"Not Found",
|
||||
"존재하지 않거나"
|
||||
]},
|
||||
{ "type": "screenshot", "name": "page_load_result" }
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 1000
|
||||
},
|
||||
{
|
||||
"type": "checkFor404",
|
||||
"indicators": [
|
||||
"페이지를 찾을 수 없습니다",
|
||||
"404",
|
||||
"Not Found",
|
||||
"존재하지 않거나"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "screenshot",
|
||||
"name": "page_load_result"
|
||||
}
|
||||
],
|
||||
"verification": [
|
||||
"현재 페이지가 404인지 확인"
|
||||
@@ -220,7 +317,10 @@
|
||||
"onError404": {
|
||||
"description": "404 에러 발생 시 대체 URL 시도",
|
||||
"actions": [
|
||||
{ "type": "log", "message": "404 감지 - 대체 경로 탐색 시작" },
|
||||
{
|
||||
"type": "log",
|
||||
"message": "404 감지 - 대체 경로 탐색 시작"
|
||||
},
|
||||
{
|
||||
"type": "tryAlternativeUrls",
|
||||
"urls": [
|
||||
@@ -239,12 +339,28 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"id": 7,
|
||||
"name": "페이지 정상 로드 확인",
|
||||
"description": "근태현황 페이지가 정상적으로 로드되었는지 확인",
|
||||
"actions": [
|
||||
{ "type": "verify", "target": "pageTitle", "contains": ["근태현황", "출퇴근", "Attendance"] },
|
||||
{ "type": "verify", "target": "pageContent", "notContains": ["404", "찾을 수 없습니다", "Not Found"] }
|
||||
{
|
||||
"type": "verify",
|
||||
"target": "pageTitle",
|
||||
"contains": [
|
||||
"근태현황",
|
||||
"출퇴근",
|
||||
"Attendance"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "verify",
|
||||
"target": "pageContent",
|
||||
"notContains": [
|
||||
"404",
|
||||
"찾을 수 없습니다",
|
||||
"Not Found"
|
||||
]
|
||||
}
|
||||
],
|
||||
"verification": [
|
||||
"페이지 제목 '근태현황' 또는 관련 텍스트 표시",
|
||||
@@ -253,11 +369,16 @@
|
||||
],
|
||||
"successCriteria": {
|
||||
"urlPattern": "/hr/attendance",
|
||||
"requiredElements": ["출퇴근", "출근", "퇴근", "현재 시간"]
|
||||
"requiredElements": [
|
||||
"출퇴근",
|
||||
"출근",
|
||||
"퇴근",
|
||||
"현재 시간"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-5",
|
||||
"id": 8,
|
||||
"name": "브라우저 위치 권한 설정",
|
||||
"description": "Playwright context에서 위치 정보 권한을 허용하고 가상 위치 설정",
|
||||
"playwright": {
|
||||
@@ -272,7 +393,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-6",
|
||||
"id": 9,
|
||||
"name": "위치 정보 로딩 대기",
|
||||
"description": "Google Map 로딩 및 현재 위치 표시 대기",
|
||||
"waitFor": {
|
||||
@@ -286,7 +407,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-7",
|
||||
"id": 10,
|
||||
"name": "사용자 정보 확인",
|
||||
"description": "출퇴근 패널에서 로그인한 사용자 정보 확인",
|
||||
"verify": {
|
||||
@@ -301,27 +422,39 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-8",
|
||||
"id": 11,
|
||||
"name": "출근 상태 확인",
|
||||
"description": "현재 출퇴근 상태 확인 (출근 전/출근 후)",
|
||||
"capture": {
|
||||
"variable": "attendanceStatus",
|
||||
"checkElements": [
|
||||
{ "selector": "button:has-text('출근하기')", "status": "not_checked_in" },
|
||||
{ "selector": "text=출근 완료", "status": "checked_in" },
|
||||
{ "selector": "button:has-text('퇴근하기')", "status": "ready_to_checkout" }
|
||||
{
|
||||
"selector": "button:has-text('출근하기')",
|
||||
"status": "not_checked_in"
|
||||
},
|
||||
{
|
||||
"selector": "text=출근 완료",
|
||||
"status": "checked_in"
|
||||
},
|
||||
{
|
||||
"selector": "button:has-text('퇴근하기')",
|
||||
"status": "ready_to_checkout"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-9",
|
||||
"id": 12,
|
||||
"name": "출근하기 (미출근 상태인 경우)",
|
||||
"description": "출근하기 버튼이 활성화된 경우 클릭하여 출근 기록",
|
||||
"condition": {
|
||||
"if": "{attendanceStatus} == 'not_checked_in'"
|
||||
},
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "출근하기" }
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "출근하기"
|
||||
}
|
||||
],
|
||||
"waitFor": {
|
||||
"type": "text",
|
||||
@@ -329,16 +462,25 @@
|
||||
"timeout": 5000
|
||||
},
|
||||
"expect": {
|
||||
"toast": ["출근", "완료", "성공"],
|
||||
"visible": ["출근 완료", "출근 시간"]
|
||||
"toast": [
|
||||
"출근",
|
||||
"완료",
|
||||
"성공"
|
||||
],
|
||||
"visible": [
|
||||
"출근 완료",
|
||||
"출근 시간"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-10",
|
||||
"id": 13,
|
||||
"name": "출근 완료 상태 확인",
|
||||
"description": "출근 완료 후 상태 및 출근 시간 표시 확인",
|
||||
"verify": {
|
||||
"visible": ["출근 완료"],
|
||||
"visible": [
|
||||
"출근 완료"
|
||||
],
|
||||
"checkInTime": {
|
||||
"format": "HH:mm:ss",
|
||||
"displayed": true
|
||||
@@ -350,7 +492,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-11",
|
||||
"id": 14,
|
||||
"name": "퇴근하기 버튼 상태 확인",
|
||||
"description": "출근 완료 후 퇴근하기 버튼 활성화 여부 확인",
|
||||
"verify": {
|
||||
@@ -362,7 +504,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-12",
|
||||
"id": 15,
|
||||
"name": "퇴근하기 (선택적)",
|
||||
"description": "퇴근하기 버튼이 활성화된 경우 클릭하여 퇴근 기록",
|
||||
"optional": true,
|
||||
@@ -370,20 +512,33 @@
|
||||
"if": "button[name='퇴근하기']:enabled"
|
||||
},
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "퇴근하기" }
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "퇴근하기"
|
||||
}
|
||||
],
|
||||
"waitFor": {
|
||||
"type": "text",
|
||||
"content": ["퇴근 완료", "퇴근 시간"],
|
||||
"content": [
|
||||
"퇴근 완료",
|
||||
"퇴근 시간"
|
||||
],
|
||||
"timeout": 5000
|
||||
},
|
||||
"expect": {
|
||||
"toast": ["퇴근", "완료", "성공"],
|
||||
"visible": ["퇴근 완료", "퇴근 시간"]
|
||||
"toast": [
|
||||
"퇴근",
|
||||
"완료",
|
||||
"성공"
|
||||
],
|
||||
"visible": [
|
||||
"퇴근 완료",
|
||||
"퇴근 시간"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-13",
|
||||
"id": 16,
|
||||
"name": "최종 상태 확인",
|
||||
"description": "출퇴근 기록 후 최종 상태 확인",
|
||||
"verify": {
|
||||
@@ -391,9 +546,14 @@
|
||||
"mapDisplayed": true,
|
||||
"attendanceRecorded": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body"
|
||||
}
|
||||
],
|
||||
|
||||
"assertions": [
|
||||
{
|
||||
"type": "url",
|
||||
@@ -417,20 +577,17 @@
|
||||
"message": "현재 시간이 표시되어야 함"
|
||||
}
|
||||
],
|
||||
|
||||
"cleanup": {
|
||||
"enabled": false,
|
||||
"description": "출퇴근 기록은 삭제하지 않음 (업무 데이터)",
|
||||
"note": "테스트 후 수동으로 관리자가 삭제 필요시 처리"
|
||||
},
|
||||
|
||||
"notes": {
|
||||
"testScope": "위치 권한 허용 -> 근태현황 페이지 이동 -> 출근/퇴근 기록 테스트",
|
||||
"antiPattern404": "직접 URL 접근 금지 - 반드시 메뉴 클릭으로 페이지 진입",
|
||||
"scrollRequired": "사이드바 스크롤을 통해 메뉴 항목 탐색 필수",
|
||||
"correctUrl": "/hr/attendance (기존 /ko/hr/attendance에서 수정됨)"
|
||||
},
|
||||
|
||||
"playwrightMcpInstructions": {
|
||||
"description": "Playwright MCP를 사용한 위치 권한 설정 방법",
|
||||
"beforeNavigation": [
|
||||
|
||||
@@ -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",
|
||||
@@ -25,54 +32,136 @@
|
||||
"action": "menu_navigate",
|
||||
"level1": "게시판",
|
||||
"level2": "게시판 관리",
|
||||
"expected": { "url_contains": "/board" }
|
||||
"expected": {
|
||||
"url_contains": "/board"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "URL 검증",
|
||||
"action": "verify_url",
|
||||
"expected": {
|
||||
"url_contains": "/board/board-management"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "목업 감지",
|
||||
"action": "verify_not_mockup"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "게시판 관리 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:게시판"]
|
||||
"id": 4,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const cards = document.querySelectorAll('[class*=\"card\"], [class*=\"Card\"], [class*=\"stat\"], [class*=\"Stat\"], [class*=\"summary\"]');\n const texts = Array.from(cards).map(c => c.innerText?.substring(0, 30)).filter(Boolean);\n return texts.length > 0 ? 'Stats: ' + texts.length + ' cards found' : 'No stat cards (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"id": 5,
|
||||
"name": "게시판 관리 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"visible_text:게시판"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "테이블 확인",
|
||||
"action": "verify_table"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"id": 7,
|
||||
"name": "목록 필터 테스트",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const selects = document.querySelectorAll('select, [role=\"combobox\"], button[class*=\"select\"], button[class*=\"Select\"]');\n if (selects.length > 0) {\n return 'Filters found: ' + selects.length;\n }\n return 'No filter dropdowns (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "검색 기능",
|
||||
"action": "search",
|
||||
"value": "테스트"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "검색 후 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:게시판"]
|
||||
"id": 9,
|
||||
"name": "검색 결과 대기",
|
||||
"action": "wait",
|
||||
"duration": 1000
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"id": 10,
|
||||
"name": "검색 결과 데이터 검증",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const rows = document.querySelectorAll('table tbody tr, [role=\"row\"]');\n return 'Search result: ' + rows.length + ' rows';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "검색 초기화",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const selectors = ['input[type=\"search\"]', 'input[placeholder*=\"검색\"]', 'input[placeholder*=\"Search\"]', 'input[role=\"searchbox\"]', '[class*=\"search\"] input'];\n for (const sel of selectors) {\n const el = document.querySelector(sel);\n if (el) {\n const nativeSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.set;\n if (nativeSetter) nativeSetter.call(el, '');\n else el.value = '';\n el.dispatchEvent(new Event('input', { bubbles: true }));\n el.dispatchEvent(new Event('change', { bubbles: true }));\n return 'Search cleared';\n }\n }\n return 'No search input found (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "검색 초기화 결과 대기",
|
||||
"action": "wait",
|
||||
"duration": 1000
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"name": "검색 초기화 및 복원 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const rows = document.querySelectorAll('table tbody tr, [role=\"row\"]');\n return 'Restored: ' + rows.length + ' rows';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"name": "검색 후 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"visible_text:게시판"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"name": "첫 번째 행 클릭",
|
||||
"action": "click_first_row"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "상세 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:게시판"]
|
||||
"id": 16,
|
||||
"name": "상세 페이지 로딩 대기",
|
||||
"action": "wait",
|
||||
"duration": 1000
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"id": 17,
|
||||
"name": "상세 페이지 - 콘텐츠 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const inputs = document.querySelectorAll('input:not([type=\"hidden\"]), textarea, select');\n const buttons = document.querySelectorAll('button');\n const hasDetail = inputs.length > 0 || document.body.innerText.includes('상세') || document.body.innerText.includes('수정');\n return hasDetail ? 'Detail page: ' + inputs.length + ' inputs, ' + buttons.length + ' buttons' : 'List page (no detail view)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"name": "상세 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"visible_text:게시판"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"name": "모달 닫기",
|
||||
"action": "close_modal_if_open"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"id": 20,
|
||||
"name": "페이지네이션 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const paginationSels = ['[class*=\"pagination\"]', '[class*=\"Pagination\"]', 'nav[aria-label*=\"page\"]', 'button[aria-label*=\"page\"]', '[class*=\"pager\"]'];\n for (const sel of paginationSels) {\n const el = document.querySelector(sel);\n if (el) return 'Pagination found';\n }\n const pageButtons = Array.from(document.querySelectorAll('button')).filter(b => /^\\d+$/.test(b.innerText?.trim()));\n if (pageButtons.length > 0) return 'Page buttons found: ' + pageButtons.length;\n return 'No pagination (ok - may have single page)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body"
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"name": "목록 복귀",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('목록'), a:has-text('목록')"
|
||||
|
||||
@@ -3,15 +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": "/company-info",
|
||||
"urlPattern": "/company-info|/ko/company-info|/settings/company-info",
|
||||
"menuHints": ["회사정보", "회사 정보", "설정"]
|
||||
"menuHints": [
|
||||
"회사정보",
|
||||
"회사 정보",
|
||||
"설정"
|
||||
]
|
||||
},
|
||||
"menuNavigation": {
|
||||
"level1": "설정",
|
||||
@@ -29,8 +39,20 @@
|
||||
"description": "사이드바를 스크롤하며 메뉴를 찾고 클릭하여 404를 방지",
|
||||
"level1": "설정",
|
||||
"level2": "회사정보",
|
||||
"alternativeLevel1Names": ["설정", "Settings", "환경설정", "시스템설정", "관리"],
|
||||
"alternativeLevel2Names": ["회사정보", "회사 정보", "Company Info", "회사관리", "기업정보"],
|
||||
"alternativeLevel1Names": [
|
||||
"설정",
|
||||
"Settings",
|
||||
"환경설정",
|
||||
"시스템설정",
|
||||
"관리"
|
||||
],
|
||||
"alternativeLevel2Names": [
|
||||
"회사정보",
|
||||
"회사 정보",
|
||||
"Company Info",
|
||||
"회사관리",
|
||||
"기업정보"
|
||||
],
|
||||
"fallbackUrls": [
|
||||
"/company-info",
|
||||
"/ko/company-info",
|
||||
@@ -45,7 +67,6 @@
|
||||
"scrollDelay": 300
|
||||
}
|
||||
},
|
||||
|
||||
"expectedAPIs": [
|
||||
{
|
||||
"method": "GET",
|
||||
@@ -63,17 +84,30 @@
|
||||
"description": "회사 추가"
|
||||
}
|
||||
],
|
||||
|
||||
"steps": [
|
||||
{
|
||||
"id": 0,
|
||||
"id": 1,
|
||||
"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": [
|
||||
"사이드바가 화면에 보이는지 확인",
|
||||
@@ -81,22 +115,41 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"id": 2,
|
||||
"name": "1차 메뉴 찾기: 설정 (스크롤 포함)",
|
||||
"description": "사이드바를 스크롤하며 '설정' 메뉴를 찾아 클릭",
|
||||
"actions": [
|
||||
{
|
||||
"type": "scrollAndFind",
|
||||
"target": "설정",
|
||||
"alternativeTexts": ["설정", "Settings", "환경설정", "시스템설정"],
|
||||
"alternativeTexts": [
|
||||
"설정",
|
||||
"Settings",
|
||||
"환경설정",
|
||||
"시스템설정"
|
||||
],
|
||||
"scrollContainer": "sidebar",
|
||||
"maxAttempts": 10,
|
||||
"description": "스크롤하며 설정 메뉴 찾기"
|
||||
},
|
||||
{ "type": "wait", "duration": 300 },
|
||||
{ "type": "click_if_exists", "target": "설정", "description": "설정 메뉴 클릭" },
|
||||
{ "type": "wait", "duration": 500, "description": "서브메뉴 펼쳐지기 대기" },
|
||||
{ "type": "screenshot", "name": "settings_menu_expanded" }
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 300
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "설정",
|
||||
"description": "설정 메뉴 클릭"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 500,
|
||||
"description": "서브메뉴 펼쳐지기 대기"
|
||||
},
|
||||
{
|
||||
"type": "screenshot",
|
||||
"name": "settings_menu_expanded"
|
||||
}
|
||||
],
|
||||
"verification": [
|
||||
"설정 메뉴가 클릭되었는지 확인",
|
||||
@@ -109,22 +162,41 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"id": 3,
|
||||
"name": "2차 메뉴 찾기: 회사정보 (스크롤 포함)",
|
||||
"description": "서브메뉴에서 '회사정보'를 찾아 클릭",
|
||||
"actions": [
|
||||
{
|
||||
"type": "scrollAndFind",
|
||||
"target": "회사정보",
|
||||
"alternativeTexts": ["회사정보", "회사 정보", "Company Info", "회사관리"],
|
||||
"alternativeTexts": [
|
||||
"회사정보",
|
||||
"회사 정보",
|
||||
"Company Info",
|
||||
"회사관리"
|
||||
],
|
||||
"scrollContainer": "submenu",
|
||||
"maxAttempts": 5,
|
||||
"description": "서브메뉴에서 회사정보 찾기"
|
||||
},
|
||||
{ "type": "wait", "duration": 200 },
|
||||
{ "type": "click_if_exists", "target": "회사정보", "description": "회사정보 메뉴 클릭" },
|
||||
{ "type": "wait", "target": "페이지 로드 완료", "timeout": 10000 },
|
||||
{ "type": "screenshot", "name": "company_info_page" }
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 200
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "회사정보",
|
||||
"description": "회사정보 메뉴 클릭"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"target": "페이지 로드 완료",
|
||||
"timeout": 10000
|
||||
},
|
||||
{
|
||||
"type": "screenshot",
|
||||
"name": "company_info_page"
|
||||
}
|
||||
],
|
||||
"verification": [
|
||||
"회사정보 메뉴 클릭 성공",
|
||||
@@ -132,18 +204,27 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"id": 4,
|
||||
"name": "404 에러 감지 및 대체 경로 시도",
|
||||
"description": "페이지 로드 후 404 에러 여부 확인, 404시 대체 경로 탐색",
|
||||
"actions": [
|
||||
{ "type": "wait", "duration": 1000 },
|
||||
{ "type": "checkFor404", "indicators": [
|
||||
"페이지를 찾을 수 없습니다",
|
||||
"404",
|
||||
"Not Found",
|
||||
"존재하지 않거나"
|
||||
]},
|
||||
{ "type": "screenshot", "name": "page_load_result" }
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 1000
|
||||
},
|
||||
{
|
||||
"type": "checkFor404",
|
||||
"indicators": [
|
||||
"페이지를 찾을 수 없습니다",
|
||||
"404",
|
||||
"Not Found",
|
||||
"존재하지 않거나"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "screenshot",
|
||||
"name": "page_load_result"
|
||||
}
|
||||
],
|
||||
"verification": [
|
||||
"현재 페이지가 404인지 확인"
|
||||
@@ -151,7 +232,10 @@
|
||||
"onError404": {
|
||||
"description": "404 에러 발생 시 대체 URL 시도",
|
||||
"actions": [
|
||||
{ "type": "log", "message": "404 감지 - 대체 경로 탐색 시작" },
|
||||
{
|
||||
"type": "log",
|
||||
"message": "404 감지 - 대체 경로 탐색 시작"
|
||||
},
|
||||
{
|
||||
"type": "tryAlternativeUrls",
|
||||
"urls": [
|
||||
@@ -169,12 +253,28 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"id": 5,
|
||||
"name": "페이지 정상 로드 확인",
|
||||
"description": "회사정보 페이지가 정상적으로 로드되었는지 확인",
|
||||
"actions": [
|
||||
{ "type": "verify", "target": "pageTitle", "contains": ["회사정보", "회사 정보", "Company"] },
|
||||
{ "type": "verify", "target": "pageContent", "notContains": ["404", "찾을 수 없습니다", "Not Found"] }
|
||||
{
|
||||
"type": "verify",
|
||||
"target": "pageTitle",
|
||||
"contains": [
|
||||
"회사정보",
|
||||
"회사 정보",
|
||||
"Company"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "verify",
|
||||
"target": "pageContent",
|
||||
"notContains": [
|
||||
"404",
|
||||
"찾을 수 없습니다",
|
||||
"Not Found"
|
||||
]
|
||||
}
|
||||
],
|
||||
"verification": [
|
||||
"페이지 제목 '회사정보' 또는 관련 텍스트 표시",
|
||||
@@ -183,7 +283,11 @@
|
||||
],
|
||||
"successCriteria": {
|
||||
"urlPattern": "/company-info",
|
||||
"requiredElements": ["회사", "회사명", "대표자명"]
|
||||
"requiredElements": [
|
||||
"회사",
|
||||
"회사명",
|
||||
"대표자명"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -192,7 +296,8 @@
|
||||
"action": "verify",
|
||||
"target": "heading",
|
||||
"expected": "회사정보",
|
||||
"validation": "페이지 제목이 '회사정보'로 표시됨"
|
||||
"validation": "페이지 제목이 '회사정보'로 표시됨",
|
||||
"id": 6
|
||||
},
|
||||
{
|
||||
"step": 6,
|
||||
@@ -200,7 +305,8 @@
|
||||
"action": "verify",
|
||||
"target": "button[text='회사 추가']",
|
||||
"expected": "button exists",
|
||||
"validation": "회사 추가 버튼이 표시됨"
|
||||
"validation": "회사 추가 버튼이 표시됨",
|
||||
"id": 7
|
||||
},
|
||||
{
|
||||
"step": 7,
|
||||
@@ -208,7 +314,8 @@
|
||||
"action": "verify",
|
||||
"target": "button[text='수정']",
|
||||
"expected": "button exists",
|
||||
"validation": "수정 버튼이 표시됨"
|
||||
"validation": "수정 버튼이 표시됨",
|
||||
"id": 8
|
||||
},
|
||||
{
|
||||
"step": 8,
|
||||
@@ -216,7 +323,8 @@
|
||||
"action": "verify",
|
||||
"target": "textbox[label='회사명'][disabled]",
|
||||
"expected": "프론트_테스트회사",
|
||||
"validation": "회사명이 표시되고 비활성화 상태"
|
||||
"validation": "회사명이 표시되고 비활성화 상태",
|
||||
"id": 9
|
||||
},
|
||||
{
|
||||
"step": 9,
|
||||
@@ -224,7 +332,8 @@
|
||||
"action": "verify",
|
||||
"target": "textbox[label='대표자명'][disabled]",
|
||||
"expected": "프론트",
|
||||
"validation": "대표자명이 표시되고 비활성화 상태"
|
||||
"validation": "대표자명이 표시되고 비활성화 상태",
|
||||
"id": 10
|
||||
},
|
||||
{
|
||||
"step": 10,
|
||||
@@ -232,7 +341,8 @@
|
||||
"action": "verify",
|
||||
"target": "textbox[label='업태'][disabled]",
|
||||
"expected": "업태명",
|
||||
"validation": "업태가 표시되고 비활성화 상태"
|
||||
"validation": "업태가 표시되고 비활성화 상태",
|
||||
"id": 11
|
||||
},
|
||||
{
|
||||
"step": 11,
|
||||
@@ -240,7 +350,8 @@
|
||||
"action": "verify",
|
||||
"target": "textbox[label='업종'][disabled]",
|
||||
"expected": "업종명",
|
||||
"validation": "업종이 표시되고 비활성화 상태"
|
||||
"validation": "업종이 표시되고 비활성화 상태",
|
||||
"id": 12
|
||||
},
|
||||
{
|
||||
"step": 12,
|
||||
@@ -248,7 +359,8 @@
|
||||
"action": "verify",
|
||||
"target": "textbox[label='주소명'][disabled]",
|
||||
"expected": "주소 표시",
|
||||
"validation": "주소가 표시되고 비활성화 상태"
|
||||
"validation": "주소가 표시되고 비활성화 상태",
|
||||
"id": 13
|
||||
},
|
||||
{
|
||||
"step": 13,
|
||||
@@ -256,7 +368,8 @@
|
||||
"action": "verify",
|
||||
"target": "textbox[label='이메일 (아이디)'][disabled]",
|
||||
"expected": "이메일 표시",
|
||||
"validation": "이메일이 표시되고 비활성화 상태"
|
||||
"validation": "이메일이 표시되고 비활성화 상태",
|
||||
"id": 14
|
||||
},
|
||||
{
|
||||
"step": 14,
|
||||
@@ -264,7 +377,8 @@
|
||||
"action": "verify",
|
||||
"target": "textbox[label='사업자등록번호'][disabled]",
|
||||
"expected": "사업자등록번호 표시",
|
||||
"validation": "사업자등록번호가 표시되고 비활성화 상태"
|
||||
"validation": "사업자등록번호가 표시되고 비활성화 상태",
|
||||
"id": 15
|
||||
},
|
||||
{
|
||||
"step": 15,
|
||||
@@ -272,7 +386,8 @@
|
||||
"action": "click_if_exists",
|
||||
"target": "button[text='수정']",
|
||||
"expected": "edit mode enabled",
|
||||
"validation": "수정 모드로 전환됨"
|
||||
"validation": "수정 모드로 전환됨",
|
||||
"id": 16
|
||||
},
|
||||
{
|
||||
"step": 16,
|
||||
@@ -280,7 +395,8 @@
|
||||
"action": "verify",
|
||||
"target": "textbox:not([disabled])",
|
||||
"expected": "fields enabled",
|
||||
"validation": "텍스트 필드들이 활성화됨"
|
||||
"validation": "텍스트 필드들이 활성화됨",
|
||||
"id": 17
|
||||
},
|
||||
{
|
||||
"step": 17,
|
||||
@@ -288,7 +404,8 @@
|
||||
"action": "click_if_exists",
|
||||
"target": "button[text='취소']",
|
||||
"expected": "edit mode disabled",
|
||||
"validation": "조회 모드로 복귀"
|
||||
"validation": "조회 모드로 복귀",
|
||||
"id": 18
|
||||
},
|
||||
{
|
||||
"step": 18,
|
||||
@@ -296,7 +413,8 @@
|
||||
"action": "click_if_exists",
|
||||
"target": "button[text='회사 추가']",
|
||||
"expected": "dialog opened",
|
||||
"validation": "회사 추가 다이얼로그가 열림"
|
||||
"validation": "회사 추가 다이얼로그가 열림",
|
||||
"id": 19
|
||||
},
|
||||
{
|
||||
"step": 19,
|
||||
@@ -304,7 +422,8 @@
|
||||
"action": "verify",
|
||||
"target": "dialog",
|
||||
"expected": "회사 추가 다이얼로그 표시",
|
||||
"validation": "다이얼로그 제목, 입력 필드, 버튼 확인"
|
||||
"validation": "다이얼로그 제목, 입력 필드, 버튼 확인",
|
||||
"id": 20
|
||||
},
|
||||
{
|
||||
"step": 20,
|
||||
@@ -312,34 +431,51 @@
|
||||
"action": "click_if_exists",
|
||||
"target": "dialog button[text='취소']",
|
||||
"expected": "dialog closed",
|
||||
"validation": "다이얼로그가 닫힘"
|
||||
"validation": "다이얼로그가 닫힘",
|
||||
"id": 21
|
||||
},
|
||||
{
|
||||
"step": 21,
|
||||
"name": "수정 모드에서 데이터 변경 테스트",
|
||||
"description": "실제 데이터를 수정하고 저장 기능 검증",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "수정", "description": "수정 모드 진입" }
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "수정",
|
||||
"description": "수정 모드 진입"
|
||||
}
|
||||
],
|
||||
"expect": {
|
||||
"fieldsEnabled": true
|
||||
}
|
||||
},
|
||||
"id": 22
|
||||
},
|
||||
{
|
||||
"step": 22,
|
||||
"name": "업태 필드 수정",
|
||||
"description": "업태 필드 값 변경",
|
||||
"actions": [
|
||||
{ "type": "clear", "target": "업태" },
|
||||
{ "type": "fill", "target": "업태", "value": "테스트업태_수정" }
|
||||
]
|
||||
{
|
||||
"type": "clear",
|
||||
"target": "업태"
|
||||
},
|
||||
{
|
||||
"type": "fill",
|
||||
"target": "업태",
|
||||
"value": "테스트업태_수정"
|
||||
}
|
||||
],
|
||||
"id": 23
|
||||
},
|
||||
{
|
||||
"step": 23,
|
||||
"name": "저장 버튼 클릭",
|
||||
"description": "수정된 회사 정보 저장",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "저장" }
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "저장"
|
||||
}
|
||||
],
|
||||
"waitFor": {
|
||||
"type": "apiResponse",
|
||||
@@ -347,8 +483,14 @@
|
||||
"timeout": 5000
|
||||
},
|
||||
"expect": {
|
||||
"toast": ["수정", "완료", "성공", "저장"]
|
||||
}
|
||||
"toast": [
|
||||
"수정",
|
||||
"완료",
|
||||
"성공",
|
||||
"저장"
|
||||
]
|
||||
},
|
||||
"id": 24
|
||||
},
|
||||
{
|
||||
"step": 24,
|
||||
@@ -360,36 +502,63 @@
|
||||
"target": "업태",
|
||||
"expected": "테스트업태_수정"
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": 25
|
||||
},
|
||||
{
|
||||
"step": 25,
|
||||
"name": "회사 추가 다이얼로그 열기",
|
||||
"description": "회사 추가 버튼 클릭하여 다이얼로그 열기",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "회사 추가" }
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "회사 추가"
|
||||
}
|
||||
],
|
||||
"expect": {
|
||||
"dialog": true,
|
||||
"visible": ["회사명", "대표자명", "사업자등록번호", "등록", "취소"]
|
||||
}
|
||||
"visible": [
|
||||
"회사명",
|
||||
"대표자명",
|
||||
"사업자등록번호",
|
||||
"등록",
|
||||
"취소"
|
||||
]
|
||||
},
|
||||
"id": 26
|
||||
},
|
||||
{
|
||||
"step": 26,
|
||||
"name": "새 회사 정보 입력",
|
||||
"description": "회사 추가 다이얼로그에서 필수 정보 입력",
|
||||
"actions": [
|
||||
{ "type": "fill", "target": "회사명", "value": "테스트회사_{timestamp}" },
|
||||
{ "type": "fill", "target": "대표자명", "value": "테스트대표" },
|
||||
{ "type": "fill", "target": "사업자등록번호", "value": "123-45-67890" }
|
||||
]
|
||||
{
|
||||
"type": "fill",
|
||||
"target": "회사명",
|
||||
"value": "테스트회사_{timestamp}"
|
||||
},
|
||||
{
|
||||
"type": "fill",
|
||||
"target": "대표자명",
|
||||
"value": "테스트대표"
|
||||
},
|
||||
{
|
||||
"type": "fill",
|
||||
"target": "사업자등록번호",
|
||||
"value": "123-45-67890"
|
||||
}
|
||||
],
|
||||
"id": 27
|
||||
},
|
||||
{
|
||||
"step": 27,
|
||||
"name": "회사 등록",
|
||||
"description": "등록 버튼 클릭하여 새 회사 등록",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "등록" }
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "등록"
|
||||
}
|
||||
],
|
||||
"waitFor": {
|
||||
"type": "apiResponse",
|
||||
@@ -397,9 +566,14 @@
|
||||
"timeout": 5000
|
||||
},
|
||||
"expect": {
|
||||
"toast": ["등록", "완료", "성공"],
|
||||
"toast": [
|
||||
"등록",
|
||||
"완료",
|
||||
"성공"
|
||||
],
|
||||
"dialogClosed": true
|
||||
}
|
||||
},
|
||||
"id": 28
|
||||
},
|
||||
{
|
||||
"step": 28,
|
||||
@@ -408,24 +582,49 @@
|
||||
"description": "등록된 회사가 목록에 표시되는지 확인",
|
||||
"verify": {
|
||||
"visible": "테스트회사"
|
||||
}
|
||||
},
|
||||
"id": 29
|
||||
},
|
||||
{
|
||||
"step": 29,
|
||||
"name": "원복: 업태 필드 원래 값으로 복구",
|
||||
"description": "테스트 후 원래 값으로 복구",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "수정" },
|
||||
{ "type": "clear", "target": "업태" },
|
||||
{ "type": "fill", "target": "업태", "value": "업태명" },
|
||||
{ "type": "click_if_exists", "target": "저장" }
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "수정"
|
||||
},
|
||||
{
|
||||
"type": "clear",
|
||||
"target": "업태"
|
||||
},
|
||||
{
|
||||
"type": "fill",
|
||||
"target": "업태",
|
||||
"value": "업태명"
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "저장"
|
||||
}
|
||||
],
|
||||
"expect": {
|
||||
"toast": ["수정", "완료", "성공", "저장"]
|
||||
}
|
||||
"toast": [
|
||||
"수정",
|
||||
"완료",
|
||||
"성공",
|
||||
"저장"
|
||||
]
|
||||
},
|
||||
"id": 30
|
||||
},
|
||||
{
|
||||
"id": 31,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body"
|
||||
}
|
||||
],
|
||||
|
||||
"notes": [
|
||||
"직접 URL 접근 금지: 반드시 메뉴 클릭으로 페이지 진입 (404 방지)",
|
||||
"스크롤 필수: 사이드바가 길 경우 메뉴가 화면 밖에 있을 수 있음",
|
||||
|
||||
@@ -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,11 +34,21 @@
|
||||
"level2": "이벤트 게시판",
|
||||
"expected": {
|
||||
"url_contains": "/customer-center",
|
||||
"visible": ["이벤트"]
|
||||
"visible": [
|
||||
"이벤트"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "URL 검증",
|
||||
"action": "verify_url",
|
||||
"expected": {
|
||||
"url_contains": "/customer-center/events"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
@@ -41,7 +58,13 @@
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"id": 4,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const cards = document.querySelectorAll('[class*=\"card\"], [class*=\"Card\"], [class*=\"stat\"], [class*=\"Stat\"], [class*=\"summary\"]');\n const texts = Array.from(cards).map(c => c.innerText?.substring(0, 30)).filter(Boolean);\n return texts.length > 0 ? 'Stats: ' + texts.length + ' cards found' : 'No stat cards (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "이벤트 페이지 구조 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -52,7 +75,7 @@
|
||||
"expected": "이벤트 페이지 구조 정상"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"id": 6,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 이벤트 목록 데이터 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -62,7 +85,7 @@
|
||||
"expected": "이벤트 데이터 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"id": 7,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 상태별 필터",
|
||||
"action": "verify_elements",
|
||||
@@ -72,7 +95,7 @@
|
||||
"expected": "상태 필터 표시"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"id": 8,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 이벤트 상세 보기",
|
||||
"action": "click_if_exists",
|
||||
@@ -82,7 +105,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"id": 9,
|
||||
"name": "이벤트 상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
@@ -94,7 +117,7 @@
|
||||
"expected": "이벤트 상세 정보 표시"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"id": 10,
|
||||
"name": "이벤트 참여 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -103,7 +126,7 @@
|
||||
"expected": "참여 버튼 확인"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"id": 11,
|
||||
"name": "공유 기능 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -112,14 +135,14 @@
|
||||
"expected": "공유 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"id": 12,
|
||||
"name": "목록으로 돌아가기",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('목록'), a:has-text('목록'), [class*='back']",
|
||||
"expected": "목록 페이지로 복귀"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"id": 13,
|
||||
"name": "페이지네이션 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -128,7 +151,35 @@
|
||||
"expected": "페이지네이션 표시"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"id": 14,
|
||||
"name": "테이블 행 클릭 - 상세 페이지 이동",
|
||||
"action": "click_first_row"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"name": "상세 페이지 로딩 대기",
|
||||
"action": "wait",
|
||||
"duration": 1000
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"name": "상세 페이지 - 콘텐츠 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const inputs = document.querySelectorAll('input:not([type=\"hidden\"]), textarea, select');\n const buttons = document.querySelectorAll('button');\n const hasDetail = inputs.length > 0 || document.body.innerText.includes('상세') || document.body.innerText.includes('수정');\n return hasDetail ? 'Detail page: ' + inputs.length + ' inputs, ' + buttons.length + ' buttons' : 'List page (no detail view)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"name": "모달/상세 닫기",
|
||||
"action": "close_modal_if_open"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body"
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"name": "이벤트 기간 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
@@ -154,7 +205,9 @@
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"steps": [
|
||||
2
|
||||
],
|
||||
"criteria": "이벤트 목록, 이벤트 카드/리스트 존재"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -42,6 +42,14 @@
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "URL 검증",
|
||||
"action": "verify_url",
|
||||
"expected": {
|
||||
"url_contains": "/customer-center/faq"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
@@ -51,7 +59,13 @@
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"id": 4,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const cards = document.querySelectorAll('[class*=\"card\"], [class*=\"Card\"], [class*=\"stat\"], [class*=\"Stat\"], [class*=\"summary\"]');\n const texts = Array.from(cards).map(c => c.innerText?.substring(0, 30)).filter(Boolean);\n return texts.length > 0 ? 'Stats: ' + texts.length + ' cards found' : 'No stat cards (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "FAQ 페이지 구조 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -62,7 +76,7 @@
|
||||
"expected": "FAQ 페이지 구조 정상"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"id": 6,
|
||||
"phase": "READ",
|
||||
"name": "[READ] FAQ 목록 데이터 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -72,7 +86,7 @@
|
||||
"expected": "FAQ 데이터 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"id": 7,
|
||||
"phase": "READ",
|
||||
"name": "[READ] FAQ 항목 펼치기",
|
||||
"action": "click_if_exists",
|
||||
@@ -82,7 +96,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"id": 8,
|
||||
"name": "FAQ 답변 내용 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
@@ -91,7 +105,7 @@
|
||||
"expected": "FAQ 답변 표시"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"id": 9,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 카테고리 필터",
|
||||
"action": "verify_element",
|
||||
@@ -99,7 +113,7 @@
|
||||
"expected": "카테고리 선택 가능"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"id": 10,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 카테고리 선택 후 결과",
|
||||
"action": "verify_detail",
|
||||
@@ -109,7 +123,7 @@
|
||||
"expected": "카테고리 필터 동작"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"id": 11,
|
||||
"phase": "SEARCH",
|
||||
"name": "[SEARCH] FAQ 검색",
|
||||
"action": "click_if_exists",
|
||||
@@ -118,7 +132,7 @@
|
||||
"submit": true
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"id": 12,
|
||||
"phase": "SEARCH",
|
||||
"name": "[SEARCH] 검색 결과 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -128,7 +142,7 @@
|
||||
"expected": "검색 기능 동작"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"id": 13,
|
||||
"name": "FAQ 접기/펼치기 토글",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -137,7 +151,19 @@
|
||||
"expected": "토글 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"id": 14,
|
||||
"name": "페이지네이션 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const paginationSels = ['[class*=\"pagination\"]', '[class*=\"Pagination\"]', 'nav[aria-label*=\"page\"]', 'button[aria-label*=\"page\"]', '[class*=\"pager\"]'];\n for (const sel of paginationSels) {\n const el = document.querySelector(sel);\n if (el) return 'Pagination found';\n }\n const pageButtons = Array.from(document.querySelectorAll('button')).filter(b => /^\\d+$/.test(b.innerText?.trim()));\n if (pageButtons.length > 0) return 'Page buttons found: ' + pageButtons.length;\n return 'No pagination (ok - may have single page)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body"
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"name": "전체 보기/접기",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
|
||||
@@ -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,11 +34,21 @@
|
||||
"level2": "공지사항",
|
||||
"expected": {
|
||||
"url_contains": "/customer-center/notices",
|
||||
"visible": ["공지사항"]
|
||||
"visible": [
|
||||
"공지사항"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "URL 검증",
|
||||
"action": "verify_url",
|
||||
"expected": {
|
||||
"url_contains": "/customer-center/notices"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
@@ -42,7 +59,13 @@
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"id": 4,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const cards = document.querySelectorAll('[class*=\"card\"], [class*=\"Card\"], [class*=\"stat\"], [class*=\"Stat\"], [class*=\"summary\"]');\n const texts = Array.from(cards).map(c => c.innerText?.substring(0, 30)).filter(Boolean);\n return texts.length > 0 ? 'Stats: ' + texts.length + ' cards found' : 'No stat cards (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "공지사항 목록 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
@@ -55,7 +78,13 @@
|
||||
"expected": "공지사항 목록 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"id": 6,
|
||||
"name": "목록 필터 테스트",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const selects = document.querySelectorAll('select, [role=\"combobox\"], button[class*=\"select\"], button[class*=\"Select\"]');\n if (selects.length > 0) {\n return 'Filters found: ' + selects.length;\n }\n return 'No filter dropdowns (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 공지사항 목록 데이터 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -65,7 +94,7 @@
|
||||
"expected": "공지사항 데이터 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"id": 8,
|
||||
"phase": "SEARCH",
|
||||
"name": "[SEARCH] 공지사항 검색",
|
||||
"action": "fill",
|
||||
@@ -74,7 +103,7 @@
|
||||
"submit": true
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"id": 9,
|
||||
"phase": "SEARCH",
|
||||
"name": "[SEARCH] 검색 결과 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -84,7 +113,7 @@
|
||||
"expected": "검색 기능 동작"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"id": 10,
|
||||
"phase": "SEARCH",
|
||||
"name": "[SEARCH] 검색 초기화",
|
||||
"action": "click_if_exists",
|
||||
@@ -92,7 +121,7 @@
|
||||
"expected": "검색 초기화"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"id": 11,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 공지사항 상세 보기",
|
||||
"action": "click_if_exists",
|
||||
@@ -103,7 +132,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"id": 12,
|
||||
"name": "상세 페이지 구조 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -115,7 +144,7 @@
|
||||
"expected": "상세 페이지 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"id": 13,
|
||||
"name": "첨부파일 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -124,7 +153,7 @@
|
||||
"expected": "첨부파일 영역 확인"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"id": 14,
|
||||
"name": "이전/다음 글 네비게이션",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -134,14 +163,14 @@
|
||||
"expected": "글 네비게이션 표시"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"id": 15,
|
||||
"name": "목록으로 돌아가기",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('목록'), a:has-text('목록'), [class*='back']",
|
||||
"expected": "목록 페이지로 복귀"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"id": 16,
|
||||
"name": "페이지네이션 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -151,7 +180,7 @@
|
||||
"expected": "페이지네이션 표시"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"id": 17,
|
||||
"name": "정렬 기능 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -160,13 +189,19 @@
|
||||
"expected": "정렬 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"id": 18,
|
||||
"name": "중요 공지 표시 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"중요/고정 공지 상단 표시 여부"
|
||||
],
|
||||
"expected": "중요 공지 표시 확인"
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
@@ -185,13 +220,19 @@
|
||||
{
|
||||
"id": 3,
|
||||
"name": "검색/필터",
|
||||
"steps": [5, 6, 7],
|
||||
"steps": [
|
||||
5,
|
||||
6,
|
||||
7
|
||||
],
|
||||
"criteria": "검색 기능 동작"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"steps": [
|
||||
2
|
||||
],
|
||||
"criteria": "공지사항 목록, 검색 기능, 목록 표시 존재"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -4,7 +4,14 @@
|
||||
"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",
|
||||
@@ -28,11 +35,21 @@
|
||||
"level2": "부서관리",
|
||||
"expected": {
|
||||
"url_contains": "/hr/department",
|
||||
"visible": ["부서관리"]
|
||||
"visible": [
|
||||
"부서관리"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "URL 검증",
|
||||
"action": "verify_url",
|
||||
"expected": {
|
||||
"url_contains": "/hr/department-management"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
@@ -42,7 +59,13 @@
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"id": 4,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const cards = document.querySelectorAll('[class*=\"card\"], [class*=\"Card\"], [class*=\"stat\"], [class*=\"Stat\"], [class*=\"summary\"]');\n const texts = Array.from(cards).map(c => c.innerText?.substring(0, 30)).filter(Boolean);\n return texts.length > 0 ? 'Stats: ' + texts.length + ' cards found' : 'No stat cards (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "부서 트리/목록 구조 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -53,7 +76,7 @@
|
||||
"expected": "부서관리 페이지 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"id": 6,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 부서 목록 데이터 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -63,14 +86,14 @@
|
||||
"expected": "부서 목록 정상"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"id": 7,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 첫 번째 부서 노드 클릭",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr:first-child, [class*='tree'] > *:first-child, li:first-child"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"id": 8,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 부서 상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -80,13 +103,13 @@
|
||||
"expected": "부서 상세 정보 확인"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"id": 9,
|
||||
"name": "부서 추가 버튼 확인",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('추가'), button:has-text('등록'), button:has-text('부서 추가')"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"id": 10,
|
||||
"name": "추가 폼/모달 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -96,13 +119,13 @@
|
||||
"expected": "부서 추가 폼 표시"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"id": 11,
|
||||
"name": "추가 모달 닫기",
|
||||
"action": "close_modal_if_open",
|
||||
"expected": "모달 닫힘"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"id": 12,
|
||||
"name": "부서 트리 구조 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -111,7 +134,7 @@
|
||||
"expected": "트리 구조 확인"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"id": 13,
|
||||
"name": "삭제 버튼 존재 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -120,7 +143,19 @@
|
||||
"expected": "삭제 기능 확인"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"id": 14,
|
||||
"name": "페이지네이션 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const paginationSels = ['[class*=\"pagination\"]', '[class*=\"Pagination\"]', 'nav[aria-label*=\"page\"]', 'button[aria-label*=\"page\"]', '[class*=\"pager\"]'];\n for (const sel of paginationSels) {\n const el = document.querySelector(sel);\n if (el) return 'Pagination found';\n }\n const pageButtons = Array.from(document.querySelectorAll('button')).filter(b => /^\\d+$/.test(b.innerText?.trim()));\n if (pageButtons.length > 0) return 'Page buttons found: ' + pageButtons.length;\n return 'No pagination (ok - may have single page)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body"
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"name": "부서관리 페이지 최종 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
@@ -140,7 +175,9 @@
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"steps": [
|
||||
2
|
||||
],
|
||||
"criteria": "부서 목록, 추가 버튼 존재"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -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": "/accounting/deposits",
|
||||
"urlPattern": "/accounting/deposits|/ko/accounting/deposits",
|
||||
"menuHints": ["입금관리", "입금 관리", "회계관리"]
|
||||
"menuHints": [
|
||||
"입금관리",
|
||||
"입금 관리",
|
||||
"회계관리"
|
||||
]
|
||||
},
|
||||
"menuNavigation": {
|
||||
"level1": "회계관리",
|
||||
@@ -25,8 +36,16 @@
|
||||
"description": "사이드바를 스크롤하며 메뉴를 찾고 클릭하여 404를 방지",
|
||||
"level1": "회계관리",
|
||||
"level2": "입금관리",
|
||||
"alternativeLevel1Names": ["회계관리", "회계 관리", "Accounting"],
|
||||
"alternativeLevel2Names": ["입금관리", "입금 관리", "Deposits"],
|
||||
"alternativeLevel1Names": [
|
||||
"회계관리",
|
||||
"회계 관리",
|
||||
"Accounting"
|
||||
],
|
||||
"alternativeLevel2Names": [
|
||||
"입금관리",
|
||||
"입금 관리",
|
||||
"Deposits"
|
||||
],
|
||||
"scrollConfig": {
|
||||
"sidebarSelector": "nav, aside, [role='navigation'], .sidebar, #sidebar",
|
||||
"menuItemSelector": "a, button, [role='menuitem'], [role='treeitem']",
|
||||
@@ -36,54 +55,97 @@
|
||||
}
|
||||
},
|
||||
"timeout": 60000,
|
||||
"tags": ["accounting", "deposit", "crud"],
|
||||
|
||||
"tags": [
|
||||
"accounting",
|
||||
"deposit",
|
||||
"crud"
|
||||
],
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
|
||||
"steps": [
|
||||
{
|
||||
"id": "step-0",
|
||||
"id": 1,
|
||||
"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
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "step-1",
|
||||
"id": 2,
|
||||
"name": "2단계 메뉴 진입: 회계관리 > 입금관리",
|
||||
"description": "사이드바를 스크롤하며 회계관리 > 입금관리 메뉴를 찾아 클릭",
|
||||
"actions": [
|
||||
{
|
||||
"type": "scrollAndFind",
|
||||
"target": "회계관리",
|
||||
"alternativeTexts": ["회계관리", "회계 관리", "Accounting"],
|
||||
"alternativeTexts": [
|
||||
"회계관리",
|
||||
"회계 관리",
|
||||
"Accounting"
|
||||
],
|
||||
"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": ["입금관리", "입금 관리", "Deposits"],
|
||||
"alternativeTexts": [
|
||||
"입금관리",
|
||||
"입금 관리",
|
||||
"Deposits"
|
||||
],
|
||||
"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
|
||||
}
|
||||
],
|
||||
"expect": {
|
||||
"url": "/accounting/deposits",
|
||||
"visible": ["입금관리", "총 입금"]
|
||||
"visible": [
|
||||
"입금관리",
|
||||
"총 입금"
|
||||
]
|
||||
},
|
||||
"verification": [
|
||||
"회계관리 메뉴가 펼쳐졌는지 확인",
|
||||
@@ -92,38 +154,87 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "step-2",
|
||||
"id": 3,
|
||||
"name": "목록 페이지 구조 확인",
|
||||
"description": "테이블 및 필터 요소 확인",
|
||||
"expect": {
|
||||
"visible": ["입금일", "입금계좌", "입금자명", "입금금액", "거래처", "적요", "입금유형"],
|
||||
"visible": [
|
||||
"입금일",
|
||||
"입금계좌",
|
||||
"입금자명",
|
||||
"입금금액",
|
||||
"거래처",
|
||||
"적요",
|
||||
"입금유형"
|
||||
],
|
||||
"elements": {
|
||||
"statisticsCards": ["총 입금", "당월 입금", "거래처 미설정", "입금유형 미설정"],
|
||||
"filters": ["계정과목명", "저장", "새로고침"],
|
||||
"statisticsCards": [
|
||||
"총 입금",
|
||||
"당월 입금",
|
||||
"거래처 미설정",
|
||||
"입금유형 미설정"
|
||||
],
|
||||
"filters": [
|
||||
"계정과목명",
|
||||
"저장",
|
||||
"새로고침"
|
||||
],
|
||||
"pagination": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-3",
|
||||
"id": 4,
|
||||
"name": "계정과목명 드롭다운 옵션 확인",
|
||||
"description": "계정과목명 일괄변경 드롭다운 옵션 검증",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "계정과목명 드롭다운", "description": "드롭다운 열기" }
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "계정과목명 드롭다운",
|
||||
"description": "드롭다운 열기"
|
||||
}
|
||||
],
|
||||
"expect": {
|
||||
"options": ["미설정", "매출대금", "선수금", "가수금", "임대수익", "이자수익", "보증금 반환", "차입금", "자본금", "부가세 환급", "기타"]
|
||||
"options": [
|
||||
"미설정",
|
||||
"매출대금",
|
||||
"선수금",
|
||||
"가수금",
|
||||
"임대수익",
|
||||
"이자수익",
|
||||
"보증금 반환",
|
||||
"차입금",
|
||||
"자본금",
|
||||
"부가세 환급",
|
||||
"기타"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-4",
|
||||
"id": 5,
|
||||
"name": "체크박스 선택 후 계정과목명 일괄변경",
|
||||
"description": "테이블 행 선택 후 계정과목명 일괄변경 저장",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "첫 번째 행 체크박스", "description": "행 선택" },
|
||||
{ "type": "click_if_exists", "target": "계정과목명 드롭다운", "description": "드롭다운 열기" },
|
||||
{ "type": "click_if_exists", "target": "매출대금", "description": "매출대금 선택" },
|
||||
{ "type": "click_if_exists", "target": "저장", "description": "저장 버튼 클릭" }
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "첫 번째 행 체크박스",
|
||||
"description": "행 선택"
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "계정과목명 드롭다운",
|
||||
"description": "드롭다운 열기"
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "매출대금",
|
||||
"description": "매출대금 선택"
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "저장",
|
||||
"description": "저장 버튼 클릭"
|
||||
}
|
||||
],
|
||||
"expect": {
|
||||
"dialog": "확인 다이얼로그 표시",
|
||||
@@ -131,7 +242,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-4-1",
|
||||
"id": 6,
|
||||
"name": "⚠️ 필수 검증: 계정과목명 변경 데이터 반영 확인",
|
||||
"note": "토스트 성공 메시지만으로 PASS 판정 불가. 실제 데이터 변경 확인 필수!",
|
||||
"description": "저장 후 테이블에서 변경된 입금유형 값 확인",
|
||||
@@ -145,100 +256,215 @@
|
||||
"knownBugReference": "BUG-SALES-20260115-001 (매출관리 동일 버그 확인 필요)"
|
||||
},
|
||||
{
|
||||
"id": "step-5",
|
||||
"id": 7,
|
||||
"name": "입금 상세 페이지 이동",
|
||||
"description": "테이블 행 클릭하여 상세 페이지로 이동",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "테이블 첫 번째 행", "description": "행 클릭 (체크박스 제외 영역)" }
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "테이블 첫 번째 행",
|
||||
"description": "행 클릭 (체크박스 제외 영역)"
|
||||
}
|
||||
],
|
||||
"expect": {
|
||||
"url": "/accounting/deposits/{id}",
|
||||
"visible": ["입금 상세", "기본 정보", "목록", "삭제", "수정"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-6",
|
||||
"name": "상세 페이지 읽기 모드 필드 확인",
|
||||
"description": "수정 전 필드들이 비활성화 상태인지 확인",
|
||||
"expect": {
|
||||
"fields": [
|
||||
{ "name": "입금일", "disabled": true },
|
||||
{ "name": "입금계좌", "disabled": true },
|
||||
{ "name": "입금자명", "disabled": true },
|
||||
{ "name": "입금금액", "disabled": true },
|
||||
{ "name": "적요", "disabled": true },
|
||||
{ "name": "거래처", "disabled": true },
|
||||
{ "name": "입금 유형", "disabled": true }
|
||||
"visible": [
|
||||
"입금 상세",
|
||||
"기본 정보",
|
||||
"목록",
|
||||
"삭제",
|
||||
"수정"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-7",
|
||||
"id": 8,
|
||||
"name": "상세 페이지 읽기 모드 필드 확인",
|
||||
"description": "수정 전 필드들이 비활성화 상태인지 확인",
|
||||
"expect": {
|
||||
"fields": [
|
||||
{
|
||||
"name": "입금일",
|
||||
"disabled": true
|
||||
},
|
||||
{
|
||||
"name": "입금계좌",
|
||||
"disabled": true
|
||||
},
|
||||
{
|
||||
"name": "입금자명",
|
||||
"disabled": true
|
||||
},
|
||||
{
|
||||
"name": "입금금액",
|
||||
"disabled": true
|
||||
},
|
||||
{
|
||||
"name": "적요",
|
||||
"disabled": true
|
||||
},
|
||||
{
|
||||
"name": "거래처",
|
||||
"disabled": true
|
||||
},
|
||||
{
|
||||
"name": "입금 유형",
|
||||
"disabled": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "수정 모드 전환",
|
||||
"description": "수정 버튼 클릭하여 편집 모드로 전환",
|
||||
"click": "수정",
|
||||
"expect": {
|
||||
"url": "/accounting/deposits/{id}?mode=edit",
|
||||
"visible": ["입금 수정", "취소", "저장"],
|
||||
"notVisible": ["목록", "삭제", "수정"]
|
||||
"visible": [
|
||||
"입금 수정",
|
||||
"취소",
|
||||
"저장"
|
||||
],
|
||||
"notVisible": [
|
||||
"목록",
|
||||
"삭제",
|
||||
"수정"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-8",
|
||||
"id": 10,
|
||||
"name": "수정 모드 필드 활성화 검증",
|
||||
"description": "수정 가능한 필드와 불가능한 필드 확인",
|
||||
"expect": {
|
||||
"fields": [
|
||||
{ "name": "입금일", "disabled": true, "note": "은행데이터 - 수정 불가" },
|
||||
{ "name": "입금계좌", "disabled": true, "note": "은행데이터 - 수정 불가" },
|
||||
{ "name": "입금자명", "disabled": true, "note": "은행데이터 - 수정 불가" },
|
||||
{ "name": "입금금액", "disabled": true, "note": "은행데이터 - 수정 불가" },
|
||||
{ "name": "적요", "disabled": false, "editable": true },
|
||||
{ "name": "거래처", "disabled": false, "type": "combobox", "editable": true },
|
||||
{ "name": "입금 유형", "disabled": false, "type": "combobox", "editable": true }
|
||||
{
|
||||
"name": "입금일",
|
||||
"disabled": true,
|
||||
"note": "은행데이터 - 수정 불가"
|
||||
},
|
||||
{
|
||||
"name": "입금계좌",
|
||||
"disabled": true,
|
||||
"note": "은행데이터 - 수정 불가"
|
||||
},
|
||||
{
|
||||
"name": "입금자명",
|
||||
"disabled": true,
|
||||
"note": "은행데이터 - 수정 불가"
|
||||
},
|
||||
{
|
||||
"name": "입금금액",
|
||||
"disabled": true,
|
||||
"note": "은행데이터 - 수정 불가"
|
||||
},
|
||||
{
|
||||
"name": "적요",
|
||||
"disabled": false,
|
||||
"editable": true
|
||||
},
|
||||
{
|
||||
"name": "거래처",
|
||||
"disabled": false,
|
||||
"type": "combobox",
|
||||
"editable": true
|
||||
},
|
||||
{
|
||||
"name": "입금 유형",
|
||||
"disabled": false,
|
||||
"type": "combobox",
|
||||
"editable": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-9",
|
||||
"id": 11,
|
||||
"name": "거래처 드롭다운 옵션 확인",
|
||||
"description": "거래처 선택 드롭다운 옵션 검증",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "거래처 드롭다운", "description": "드롭다운 열기" }
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "거래처 드롭다운",
|
||||
"description": "드롭다운 열기"
|
||||
}
|
||||
],
|
||||
"expect": {
|
||||
"options": ["거래처테스트", "아크더레드", "코브라브릿지", "가우스전자", "아크아크"]
|
||||
"options": [
|
||||
"거래처테스트",
|
||||
"아크더레드",
|
||||
"코브라브릿지",
|
||||
"가우스전자",
|
||||
"아크아크"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-10",
|
||||
"id": 12,
|
||||
"name": "입금 유형 드롭다운 옵션 확인",
|
||||
"description": "입금 유형 선택 드롭다운 옵션 검증",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "입금 유형 드롭다운", "description": "드롭다운 열기" }
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "입금 유형 드롭다운",
|
||||
"description": "드롭다운 열기"
|
||||
}
|
||||
],
|
||||
"expect": {
|
||||
"options": ["미설정", "매출대금", "선수금", "가수금", "임대수익", "이자수익", "보증금 반환", "차입금", "자본금", "부가세 환급", "기타"]
|
||||
"options": [
|
||||
"미설정",
|
||||
"매출대금",
|
||||
"선수금",
|
||||
"가수금",
|
||||
"임대수익",
|
||||
"이자수익",
|
||||
"보증금 반환",
|
||||
"차입금",
|
||||
"자본금",
|
||||
"부가세 환급",
|
||||
"기타"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-11",
|
||||
"id": 13,
|
||||
"name": "수정 데이터 입력",
|
||||
"description": "수정 가능한 필드에 테스트 데이터 입력",
|
||||
"form": {
|
||||
"fields": [
|
||||
{ "name": "적요", "type": "text", "value": "테스트 적요 수정" }
|
||||
{
|
||||
"name": "적요",
|
||||
"type": "text",
|
||||
"value": "테스트 적요 수정"
|
||||
}
|
||||
]
|
||||
},
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "거래처 드롭다운", "description": "거래처 드롭다운 열기" },
|
||||
{ "type": "click_if_exists", "target": "거래처테스트", "description": "거래처 선택" },
|
||||
{ "type": "click_if_exists", "target": "입금 유형 드롭다운", "description": "입금 유형 드롭다운 열기" },
|
||||
{ "type": "click_if_exists", "target": "매출대금", "description": "매출대금 선택" }
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "거래처 드롭다운",
|
||||
"description": "거래처 드롭다운 열기"
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "거래처테스트",
|
||||
"description": "거래처 선택"
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "입금 유형 드롭다운",
|
||||
"description": "입금 유형 드롭다운 열기"
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "매출대금",
|
||||
"description": "매출대금 선택"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "step-12",
|
||||
"id": 14,
|
||||
"name": "저장 및 결과 확인",
|
||||
"description": "저장 버튼 클릭 후 데이터 반영 확인",
|
||||
"click": "저장",
|
||||
@@ -249,61 +475,105 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-12-1",
|
||||
"id": 15,
|
||||
"name": "⚠️ 필수 검증: 수정 데이터 반영 확인",
|
||||
"note": "토스트 성공 메시지만으로 PASS 판정 불가. 실제 데이터 변경 확인 필수!",
|
||||
"description": "저장 후 상세 페이지에서 변경된 값 확인",
|
||||
"expect": {
|
||||
"fields": [
|
||||
{ "name": "적요", "value": "테스트 적요 수정" },
|
||||
{ "name": "거래처", "value": "거래처테스트" },
|
||||
{ "name": "입금 유형", "value": "매출대금" }
|
||||
{
|
||||
"name": "적요",
|
||||
"value": "테스트 적요 수정"
|
||||
},
|
||||
{
|
||||
"name": "거래처",
|
||||
"value": "거래처테스트"
|
||||
},
|
||||
{
|
||||
"name": "입금 유형",
|
||||
"value": "매출대금"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-13",
|
||||
"id": 16,
|
||||
"name": "취소 버튼 동작 확인",
|
||||
"description": "수정 모드에서 취소 버튼 동작 검증",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "수정", "description": "수정 모드 진입" },
|
||||
{ "type": "click_if_exists", "target": "취소", "description": "취소 버튼 클릭" }
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "수정",
|
||||
"description": "수정 모드 진입"
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "취소",
|
||||
"description": "취소 버튼 클릭"
|
||||
}
|
||||
],
|
||||
"expect": {
|
||||
"url": "/accounting/deposits/{id}",
|
||||
"mode": "view",
|
||||
"visible": ["입금 상세", "목록", "삭제", "수정"]
|
||||
"visible": [
|
||||
"입금 상세",
|
||||
"목록",
|
||||
"삭제",
|
||||
"수정"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-14",
|
||||
"id": 17,
|
||||
"name": "목록 버튼 동작 확인",
|
||||
"description": "목록 버튼 클릭하여 목록 페이지로 이동",
|
||||
"click": "목록",
|
||||
"expect": {
|
||||
"url": "/accounting/deposits",
|
||||
"visible": ["입금관리", "총 입금"]
|
||||
"visible": [
|
||||
"입금관리",
|
||||
"총 입금"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-15",
|
||||
"id": 18,
|
||||
"name": "필터 드롭다운 검증",
|
||||
"description": "목록 페이지 필터 드롭다운 옵션 확인",
|
||||
"note": "3개의 필터 드롭다운 존재 (거래처, 입금유형, 정렬)",
|
||||
"expect": {
|
||||
"filters": [
|
||||
{ "name": "거래처 필터", "default": "전체" },
|
||||
{ "name": "입금유형 필터", "default": "전체" },
|
||||
{ "name": "정렬", "default": "최신순", "options": ["최신순", "등록순", "금액 높은순", "금액 낮은순"] }
|
||||
{
|
||||
"name": "거래처 필터",
|
||||
"default": "전체"
|
||||
},
|
||||
{
|
||||
"name": "입금유형 필터",
|
||||
"default": "전체"
|
||||
},
|
||||
{
|
||||
"name": "정렬",
|
||||
"default": "최신순",
|
||||
"options": [
|
||||
"최신순",
|
||||
"등록순",
|
||||
"금액 높은순",
|
||||
"금액 낮은순"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-16",
|
||||
"id": 19,
|
||||
"name": "날짜 필터 검증",
|
||||
"description": "날짜 필터 버튼 동작 확인",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "당해년도", "description": "당해년도 버튼 클릭" }
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "당해년도",
|
||||
"description": "당해년도 버튼 클릭"
|
||||
}
|
||||
],
|
||||
"expect": {
|
||||
"dateRange": {
|
||||
@@ -313,7 +583,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-17",
|
||||
"id": 20,
|
||||
"name": "페이지네이션 동작 확인",
|
||||
"description": "페이지네이션 버튼 동작 검증",
|
||||
"expect": {
|
||||
@@ -325,15 +595,24 @@
|
||||
}
|
||||
},
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "다음", "description": "다음 페이지로 이동" }
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "다음",
|
||||
"description": "다음 페이지로 이동"
|
||||
}
|
||||
],
|
||||
"expectAfterAction": {
|
||||
"currentPage": 2,
|
||||
"displayText": "전체 60개 중 21-40개 표시"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body"
|
||||
}
|
||||
],
|
||||
|
||||
"deleteTest": {
|
||||
"note": "삭제 테스트 - 이전에 스킵되었으나 CRUD 완전성을 위해 추가",
|
||||
"steps": [
|
||||
@@ -342,11 +621,17 @@
|
||||
"name": "삭제 버튼 클릭",
|
||||
"description": "상세 페이지에서 삭제 버튼 클릭",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "삭제" }
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "삭제"
|
||||
}
|
||||
],
|
||||
"expect": {
|
||||
"confirmDialog": true,
|
||||
"dialogText": ["삭제", "하시겠습니까"]
|
||||
"dialogText": [
|
||||
"삭제",
|
||||
"하시겠습니까"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -354,7 +639,11 @@
|
||||
"name": "삭제 확인",
|
||||
"description": "삭제 확인 다이얼로그에서 확인 클릭",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "확인", "description": "삭제 확인" }
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "확인",
|
||||
"description": "삭제 확인"
|
||||
}
|
||||
],
|
||||
"waitFor": {
|
||||
"type": "navigation",
|
||||
@@ -362,7 +651,11 @@
|
||||
"timeout": 5000
|
||||
},
|
||||
"expect": {
|
||||
"toast": ["삭제", "완료", "성공"],
|
||||
"toast": [
|
||||
"삭제",
|
||||
"완료",
|
||||
"성공"
|
||||
],
|
||||
"url": "/accounting/deposits"
|
||||
}
|
||||
},
|
||||
@@ -377,16 +670,16 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"knownBugs": [
|
||||
{
|
||||
"id": "BUG-SALES-20260115-001",
|
||||
"description": "계정과목명 일괄변경 시 토스트 성공 표시되나 실제 데이터 미변경 (매출관리)",
|
||||
"relatedSteps": ["step-4-1"],
|
||||
"relatedSteps": [
|
||||
"step-4-1"
|
||||
],
|
||||
"note": "입금관리에서도 동일한 버그가 존재할 수 있으므로 step-4-1에서 검증 필수"
|
||||
}
|
||||
],
|
||||
|
||||
"testData": {
|
||||
"sampleDeposit": {
|
||||
"date": "2025-12-28",
|
||||
@@ -403,55 +696,129 @@
|
||||
"depositType": "매출대금"
|
||||
}
|
||||
},
|
||||
|
||||
"pageStructure": {
|
||||
"listPage": {
|
||||
"url": "/accounting/deposits",
|
||||
"title": "입금관리",
|
||||
"statistics": ["총 입금", "당월 입금", "거래처 미설정", "입금유형 미설정"],
|
||||
"tableColumns": ["checkbox", "입금일", "입금계좌", "입금자명", "입금금액", "거래처", "적요", "입금유형", "action"],
|
||||
"statistics": [
|
||||
"총 입금",
|
||||
"당월 입금",
|
||||
"거래처 미설정",
|
||||
"입금유형 미설정"
|
||||
],
|
||||
"tableColumns": [
|
||||
"checkbox",
|
||||
"입금일",
|
||||
"입금계좌",
|
||||
"입금자명",
|
||||
"입금금액",
|
||||
"거래처",
|
||||
"적요",
|
||||
"입금유형",
|
||||
"action"
|
||||
],
|
||||
"batchUpdate": {
|
||||
"label": "계정과목명",
|
||||
"saveButton": "저장"
|
||||
},
|
||||
"filters": ["거래처", "입금유형", "정렬"],
|
||||
"dateFilters": ["당해년도", "전전월", "전월", "당월", "어제", "오늘"]
|
||||
"filters": [
|
||||
"거래처",
|
||||
"입금유형",
|
||||
"정렬"
|
||||
],
|
||||
"dateFilters": [
|
||||
"당해년도",
|
||||
"전전월",
|
||||
"전월",
|
||||
"당월",
|
||||
"어제",
|
||||
"오늘"
|
||||
]
|
||||
},
|
||||
"detailPage": {
|
||||
"url": "/accounting/deposits/{id}",
|
||||
"title": "입금 상세",
|
||||
"buttons": ["목록", "삭제", "수정"],
|
||||
"buttons": [
|
||||
"목록",
|
||||
"삭제",
|
||||
"수정"
|
||||
],
|
||||
"fields": {
|
||||
"readOnly": ["입금일", "입금계좌", "입금자명", "입금금액"],
|
||||
"editable": ["적요", "거래처", "입금 유형"]
|
||||
"readOnly": [
|
||||
"입금일",
|
||||
"입금계좌",
|
||||
"입금자명",
|
||||
"입금금액"
|
||||
],
|
||||
"editable": [
|
||||
"적요",
|
||||
"거래처",
|
||||
"입금 유형"
|
||||
]
|
||||
}
|
||||
},
|
||||
"editPage": {
|
||||
"url": "/accounting/deposits/{id}?mode=edit",
|
||||
"title": "입금 수정",
|
||||
"buttons": ["취소", "저장"]
|
||||
"buttons": [
|
||||
"취소",
|
||||
"저장"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
"dropdownOptions": {
|
||||
"accountSubject": {
|
||||
"label": "계정과목명",
|
||||
"options": ["미설정", "매출대금", "선수금", "가수금", "임대수익", "이자수익", "보증금 반환", "차입금", "자본금", "부가세 환급", "기타"]
|
||||
"options": [
|
||||
"미설정",
|
||||
"매출대금",
|
||||
"선수금",
|
||||
"가수금",
|
||||
"임대수익",
|
||||
"이자수익",
|
||||
"보증금 반환",
|
||||
"차입금",
|
||||
"자본금",
|
||||
"부가세 환급",
|
||||
"기타"
|
||||
]
|
||||
},
|
||||
"depositType": {
|
||||
"label": "입금 유형",
|
||||
"options": ["미설정", "매출대금", "선수금", "가수금", "임대수익", "이자수익", "보증금 반환", "차입금", "자본금", "부가세 환급", "기타"]
|
||||
"options": [
|
||||
"미설정",
|
||||
"매출대금",
|
||||
"선수금",
|
||||
"가수금",
|
||||
"임대수익",
|
||||
"이자수익",
|
||||
"보증금 반환",
|
||||
"차입금",
|
||||
"자본금",
|
||||
"부가세 환급",
|
||||
"기타"
|
||||
]
|
||||
},
|
||||
"vendor": {
|
||||
"label": "거래처",
|
||||
"options": ["거래처테스트", "아크더레드", "코브라브릿지", "가우스전자", "아크아크"]
|
||||
"options": [
|
||||
"거래처테스트",
|
||||
"아크더레드",
|
||||
"코브라브릿지",
|
||||
"가우스전자",
|
||||
"아크아크"
|
||||
]
|
||||
},
|
||||
"sortOrder": {
|
||||
"label": "정렬",
|
||||
"options": ["최신순", "등록순", "금액 높은순", "금액 낮은순"]
|
||||
"options": [
|
||||
"최신순",
|
||||
"등록순",
|
||||
"금액 높은순",
|
||||
"금액 낮은순"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
"assertions": [
|
||||
{
|
||||
"type": "url",
|
||||
|
||||
@@ -4,7 +4,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",
|
||||
@@ -28,11 +35,21 @@
|
||||
"level2": "기안함",
|
||||
"expected": {
|
||||
"url_contains": "/approval/draft",
|
||||
"visible": ["기안함"]
|
||||
"visible": [
|
||||
"기안함"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "URL 검증",
|
||||
"action": "verify_url",
|
||||
"expected": {
|
||||
"url_contains": "/approval/draft"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
@@ -43,7 +60,7 @@
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"id": 4,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "verify_element",
|
||||
"checks": [
|
||||
@@ -55,7 +72,7 @@
|
||||
"expected": "통계 카드 4개 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"id": 5,
|
||||
"name": "기안함 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
@@ -69,7 +86,13 @@
|
||||
"expected": "기안함 테이블 컬럼 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"id": 6,
|
||||
"name": "목록 필터 테스트",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const selects = document.querySelectorAll('select, [role=\"combobox\"], button[class*=\"select\"], button[class*=\"Select\"]');\n if (selects.length > 0) {\n return 'Filters found: ' + selects.length;\n }\n return 'No filter dropdowns (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "데이터 로드 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
@@ -78,7 +101,7 @@
|
||||
"expected": "기안 문서 데이터 표시"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"id": 8,
|
||||
"phase": "SEARCH",
|
||||
"name": "[SEARCH] 검색 기능 테스트",
|
||||
"action": "fill",
|
||||
@@ -87,7 +110,7 @@
|
||||
"submit": true
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"id": 9,
|
||||
"phase": "SEARCH",
|
||||
"name": "[SEARCH] 검색 결과 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -97,7 +120,7 @@
|
||||
"expected": "검색 기능 동작"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"id": 10,
|
||||
"phase": "SEARCH",
|
||||
"name": "[SEARCH] 검색 초기화",
|
||||
"action": "click_if_exists",
|
||||
@@ -105,14 +128,14 @@
|
||||
"expected": "검색 초기화"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"id": 11,
|
||||
"name": "필터 기능 테스트",
|
||||
"action": "click_if_exists",
|
||||
"target": "select, [role='combobox'], button:has-text('임시저장')",
|
||||
"expected": "필터 옵션 표시"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"id": 12,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 문서 상세 보기",
|
||||
"action": "click_if_exists",
|
||||
@@ -122,7 +145,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"id": 13,
|
||||
"name": "상세 페이지/모달 확인",
|
||||
"action": "verify_element",
|
||||
"checks": [
|
||||
@@ -132,13 +155,13 @@
|
||||
"expected": "상세 정보 표시"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"id": 14,
|
||||
"name": "모달/상세 닫기",
|
||||
"action": "close_modal_if_open",
|
||||
"expected": "모달 닫힘"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"id": 15,
|
||||
"name": "페이지네이션 확인",
|
||||
"action": "verify_element",
|
||||
"checks": [
|
||||
@@ -147,13 +170,19 @@
|
||||
"expected": "페이지네이션 표시"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"id": 16,
|
||||
"name": "문서 작성 버튼 확인",
|
||||
"action": "verify_element",
|
||||
"checks": [
|
||||
"문서 작성 또는 신규 작성 버튼 존재"
|
||||
],
|
||||
"expected": "문서 작성 버튼 확인"
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
@@ -172,13 +201,19 @@
|
||||
{
|
||||
"id": 3,
|
||||
"name": "검색/필터",
|
||||
"steps": [6, 7, 8],
|
||||
"steps": [
|
||||
6,
|
||||
7,
|
||||
8
|
||||
],
|
||||
"criteria": "검색 기능 동작"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"steps": [
|
||||
2
|
||||
],
|
||||
"criteria": "기안함 목록, 검색 기능, 문서 작성 버튼 존재"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -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/employee-management",
|
||||
"urlPattern": "/hr/employee-management|/ko/hr/employee-management",
|
||||
"menuHints": ["사원관리", "사원 관리", "인사관리"]
|
||||
"menuHints": [
|
||||
"사원관리",
|
||||
"사원 관리",
|
||||
"인사관리"
|
||||
]
|
||||
},
|
||||
"menuNavigation": {
|
||||
"level1": "인사관리",
|
||||
@@ -36,16 +47,18 @@
|
||||
"timeout": 10000
|
||||
},
|
||||
"timeout": 60000,
|
||||
"tags": ["hr", "employee", "crud"],
|
||||
|
||||
"tags": [
|
||||
"hr",
|
||||
"employee",
|
||||
"crud"
|
||||
],
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
|
||||
"steps": [
|
||||
{
|
||||
"id": "step-0",
|
||||
"id": 1,
|
||||
"name": "사이드바 메뉴 전체 펼치기",
|
||||
"description": "모두 펼치기 버튼을 클릭하여 전체 메뉴를 펼친 후 메뉴 탐색 준비",
|
||||
"actions": [
|
||||
@@ -54,7 +67,10 @@
|
||||
"script": "document.querySelector('.sidebar-scroll, [class*=\"sidebar\"], nav')?.scrollTo({top: 0, behavior: 'instant'})",
|
||||
"description": "사이드바 스크롤 최상단으로 이동"
|
||||
},
|
||||
{ "type": "wait", "duration": 300 },
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 300
|
||||
},
|
||||
{
|
||||
"type": "evaluate",
|
||||
"script": "Array.from(document.querySelectorAll('button')).find(b => b.innerText?.includes('모두 펼치기'))?.click()",
|
||||
@@ -68,7 +84,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "step-1",
|
||||
"id": 2,
|
||||
"name": "인사관리 메뉴 진입",
|
||||
"description": "인사관리 > 직원관리 메뉴로 이동 (scrollAndFind 패턴)",
|
||||
"menuNavigation": {
|
||||
@@ -86,92 +102,176 @@
|
||||
},
|
||||
"expect": {
|
||||
"url": "/hr/employee-management",
|
||||
"visible": ["사원관리", "사원 등록"]
|
||||
"visible": [
|
||||
"사원관리",
|
||||
"사원 등록"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-2",
|
||||
"id": 3,
|
||||
"name": "사원 등록 페이지 이동",
|
||||
"click": "사원 등록",
|
||||
"expect": {
|
||||
"url": "/hr/employee-management?mode=new",
|
||||
"visible": ["사원 등록", "사원 정보"]
|
||||
"visible": [
|
||||
"사원 등록",
|
||||
"사원 정보"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-3",
|
||||
"id": 4,
|
||||
"name": "사원 정보 입력",
|
||||
"description": "기본 사원 정보 입력",
|
||||
"form": {
|
||||
"fields": [
|
||||
{ "name": "이름 *", "type": "text", "value": "홍길동" },
|
||||
{ "name": "주민등록번호", "type": "text", "value": "900101-1234567" },
|
||||
{ "name": "휴대폰", "type": "text", "value": "010-1234-5678" },
|
||||
{ "name": "이메일 *", "type": "text", "value": "test.employee@codebridge-x.com" },
|
||||
{ "name": "연봉", "type": "number", "value": "50000000" }
|
||||
{
|
||||
"name": "이름 *",
|
||||
"type": "text",
|
||||
"value": "홍길동"
|
||||
},
|
||||
{
|
||||
"name": "주민등록번호",
|
||||
"type": "text",
|
||||
"value": "900101-1234567"
|
||||
},
|
||||
{
|
||||
"name": "휴대폰",
|
||||
"type": "text",
|
||||
"value": "010-1234-5678"
|
||||
},
|
||||
{
|
||||
"name": "이메일 *",
|
||||
"type": "text",
|
||||
"value": "test.employee@codebridge-x.com"
|
||||
},
|
||||
{
|
||||
"name": "연봉",
|
||||
"type": "number",
|
||||
"value": "50000000"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-4",
|
||||
"id": 5,
|
||||
"name": "급여계좌 정보 입력",
|
||||
"form": {
|
||||
"fields": [
|
||||
{ "name": "은행명", "type": "text", "value": "신한은행" },
|
||||
{ "name": "계좌번호", "type": "text", "value": "110-123-456789" },
|
||||
{ "name": "예금주", "type": "text", "value": "홍길동" }
|
||||
{
|
||||
"name": "은행명",
|
||||
"type": "text",
|
||||
"value": "신한은행"
|
||||
},
|
||||
{
|
||||
"name": "계좌번호",
|
||||
"type": "text",
|
||||
"value": "110-123-456789"
|
||||
},
|
||||
{
|
||||
"name": "예금주",
|
||||
"type": "text",
|
||||
"value": "홍길동"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-5",
|
||||
"id": 6,
|
||||
"name": "사원 상세 정보 입력",
|
||||
"form": {
|
||||
"fields": [
|
||||
{ "name": "사원코드", "type": "text", "value": "EMP2026001" },
|
||||
{ "name": "남성", "type": "radio", "value": "true" },
|
||||
{ "name": "상세주소를 입력해주세요", "type": "text", "value": "123번지 4층" }
|
||||
{
|
||||
"name": "사원코드",
|
||||
"type": "text",
|
||||
"value": "EMP2026001"
|
||||
},
|
||||
{
|
||||
"name": "남성",
|
||||
"type": "radio",
|
||||
"value": "true"
|
||||
},
|
||||
{
|
||||
"name": "상세주소를 입력해주세요",
|
||||
"type": "text",
|
||||
"value": "123번지 4층"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-6",
|
||||
"id": 7,
|
||||
"name": "인사 정보 입력",
|
||||
"form": {
|
||||
"fields": [
|
||||
{ "name": "입사일", "type": "date", "value": "2026-01-14" }
|
||||
{
|
||||
"name": "입사일",
|
||||
"type": "date",
|
||||
"value": "2026-01-14"
|
||||
}
|
||||
]
|
||||
},
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "고용형태 선택", "description": "고용형태 드롭다운 열기" },
|
||||
{ "type": "click_if_exists", "target": "정규직", "description": "정규직 선택" },
|
||||
{ "type": "click_if_exists", "target": "직급 선택", "description": "직급 드롭다운 열기" },
|
||||
{ "type": "click_if_exists", "target": "사원", "description": "사원 직급 선택" }
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "고용형태 선택",
|
||||
"description": "고용형태 드롭다운 열기"
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "정규직",
|
||||
"description": "정규직 선택"
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "직급 선택",
|
||||
"description": "직급 드롭다운 열기"
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "사원",
|
||||
"description": "사원 직급 선택"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "step-7",
|
||||
"id": 8,
|
||||
"name": "사용자 정보 입력",
|
||||
"form": {
|
||||
"fields": [
|
||||
{ "name": "아이디 *", "type": "text", "value": "testuser2026" },
|
||||
{ "name": "비밀번호 *", "type": "text", "value": "password123!" },
|
||||
{ "name": "비밀번호 확인 *", "type": "text", "value": "password123!" }
|
||||
{
|
||||
"name": "아이디 *",
|
||||
"type": "text",
|
||||
"value": "testuser2026"
|
||||
},
|
||||
{
|
||||
"name": "비밀번호 *",
|
||||
"type": "text",
|
||||
"value": "password123!"
|
||||
},
|
||||
{
|
||||
"name": "비밀번호 확인 *",
|
||||
"type": "text",
|
||||
"value": "password123!"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-8",
|
||||
"id": 9,
|
||||
"name": "등록 완료",
|
||||
"click": "등록",
|
||||
"waitFor": "사원관리",
|
||||
"expect": {
|
||||
"url": "/hr/employee-management",
|
||||
"text": ["홍길동"]
|
||||
"text": [
|
||||
"홍길동"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-8-1",
|
||||
"id": 10,
|
||||
"name": "검색 기간 설정 - 유효 기간",
|
||||
"description": "등록된 사원의 입사일(2026-01-14)이 포함되는 기간으로 검색",
|
||||
"actions": [
|
||||
@@ -200,7 +300,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-8-2",
|
||||
"id": 11,
|
||||
"name": "검색 기간 설정 - 범위 외 기간",
|
||||
"description": "등록된 사원의 입사일이 포함되지 않는 기간으로 검색하여 검색되지 않음을 확인",
|
||||
"actions": [
|
||||
@@ -240,19 +340,26 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-8-3",
|
||||
"id": 12,
|
||||
"name": "검색 기간 초기화 및 전체 조회",
|
||||
"description": "검색 조건 초기화하여 등록된 사원이 다시 표시되는지 확인",
|
||||
"actions": [
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "초기화",
|
||||
"fallbackSelectors": ["button:has-text('초기화')", ".reset-btn", "button:has-text('Reset')"]
|
||||
"fallbackSelectors": [
|
||||
"button:has-text('초기화')",
|
||||
".reset-btn",
|
||||
"button:has-text('Reset')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "검색",
|
||||
"fallbackSelectors": ["button:has-text('검색')", ".search-btn"]
|
||||
"fallbackSelectors": [
|
||||
"button:has-text('검색')",
|
||||
".search-btn"
|
||||
]
|
||||
}
|
||||
],
|
||||
"expect": {
|
||||
@@ -266,7 +373,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-9",
|
||||
"id": 13,
|
||||
"name": "등록된 직원 상세 페이지 이동",
|
||||
"description": "등록된 직원을 클릭하여 상세 페이지로 이동",
|
||||
"actions": [
|
||||
@@ -278,42 +385,61 @@
|
||||
],
|
||||
"expect": {
|
||||
"url": "/hr/employee-management/{id}",
|
||||
"visible": ["사원 상세", "수정", "삭제", "목록"]
|
||||
"visible": [
|
||||
"사원 상세",
|
||||
"수정",
|
||||
"삭제",
|
||||
"목록"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-10",
|
||||
"id": 14,
|
||||
"name": "직원 수정 모드 전환",
|
||||
"description": "수정 버튼 클릭하여 편집 모드로 전환",
|
||||
"click": "수정",
|
||||
"expect": {
|
||||
"url": "/hr/employee-management/{id}?mode=edit",
|
||||
"visible": ["사원 수정", "취소", "저장"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-11",
|
||||
"name": "직원 정보 수정",
|
||||
"description": "휴대폰 번호 변경",
|
||||
"form": {
|
||||
"fields": [
|
||||
{ "name": "휴대폰", "type": "text", "value": "010-9999-8888", "clear": true }
|
||||
"visible": [
|
||||
"사원 수정",
|
||||
"취소",
|
||||
"저장"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-12",
|
||||
"id": 15,
|
||||
"name": "직원 정보 수정",
|
||||
"description": "휴대폰 번호 변경",
|
||||
"form": {
|
||||
"fields": [
|
||||
{
|
||||
"name": "휴대폰",
|
||||
"type": "text",
|
||||
"value": "010-9999-8888",
|
||||
"clear": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"name": "수정 저장",
|
||||
"description": "수정된 직원 정보 저장",
|
||||
"click": "저장",
|
||||
"waitFor": "사원 상세",
|
||||
"expect": {
|
||||
"toast": ["수정", "완료", "성공", "저장"],
|
||||
"toast": [
|
||||
"수정",
|
||||
"완료",
|
||||
"성공",
|
||||
"저장"
|
||||
],
|
||||
"url": "/hr/employee-management/{id}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-12-1",
|
||||
"id": 17,
|
||||
"name": "⚠️ 필수 검증: 수정 데이터 반영 확인",
|
||||
"note": "토스트 성공 메시지만으로 PASS 판정 불가. 실제 데이터 변경 확인 필수!",
|
||||
"description": "상세 페이지에서 수정된 휴대폰 번호 확인",
|
||||
@@ -325,37 +451,49 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-13",
|
||||
"id": 18,
|
||||
"name": "직원 삭제",
|
||||
"description": "삭제 버튼 클릭하여 직원 삭제",
|
||||
"click": "삭제",
|
||||
"expect": {
|
||||
"confirmDialog": true,
|
||||
"dialogText": ["삭제", "하시겠습니까"]
|
||||
"dialogText": [
|
||||
"삭제",
|
||||
"하시겠습니까"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-14",
|
||||
"id": 19,
|
||||
"name": "삭제 확인",
|
||||
"description": "삭제 확인 다이얼로그에서 확인 클릭",
|
||||
"click": "확인",
|
||||
"waitFor": "사원관리",
|
||||
"expect": {
|
||||
"toast": ["삭제", "완료", "성공"],
|
||||
"toast": [
|
||||
"삭제",
|
||||
"완료",
|
||||
"성공"
|
||||
],
|
||||
"url": "/hr/employee-management"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-15",
|
||||
"id": 20,
|
||||
"name": "⚠️ 필수 검증: 삭제 데이터 반영 확인",
|
||||
"note": "토스트 성공 메시지만으로 PASS 판정 불가. 실제 데이터 삭제 확인 필수!",
|
||||
"description": "목록에서 삭제된 직원이 없어졌는지 확인",
|
||||
"verify": {
|
||||
"tableNotContains": "홍길동"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body"
|
||||
}
|
||||
],
|
||||
|
||||
"assertions": [
|
||||
{
|
||||
"type": "url",
|
||||
|
||||
127
free-board.json
127
free-board.json
@@ -4,7 +4,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",
|
||||
@@ -26,54 +33,136 @@
|
||||
"action": "menu_navigate",
|
||||
"level1": "게시판",
|
||||
"level2": "자유게시판",
|
||||
"expected": { "url_contains": "/boards/free" }
|
||||
"expected": {
|
||||
"url_contains": "/boards/free"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "URL 검증",
|
||||
"action": "verify_url",
|
||||
"expected": {
|
||||
"url_contains": "/boards/free"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "목업 감지",
|
||||
"action": "verify_not_mockup"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "자유게시판 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:게시판"]
|
||||
"id": 4,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const cards = document.querySelectorAll('[class*=\"card\"], [class*=\"Card\"], [class*=\"stat\"], [class*=\"Stat\"], [class*=\"summary\"]');\n const texts = Array.from(cards).map(c => c.innerText?.substring(0, 30)).filter(Boolean);\n return texts.length > 0 ? 'Stats: ' + texts.length + ' cards found' : 'No stat cards (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"id": 5,
|
||||
"name": "자유게시판 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"visible_text:게시판"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "테이블 확인",
|
||||
"action": "verify_table"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"id": 7,
|
||||
"name": "목록 필터 테스트",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const selects = document.querySelectorAll('select, [role=\"combobox\"], button[class*=\"select\"], button[class*=\"Select\"]');\n if (selects.length > 0) {\n return 'Filters found: ' + selects.length;\n }\n return 'No filter dropdowns (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "검색 기능",
|
||||
"action": "search",
|
||||
"value": "테스트"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "검색 후 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:게시판"]
|
||||
"id": 9,
|
||||
"name": "검색 결과 대기",
|
||||
"action": "wait",
|
||||
"duration": 1000
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"id": 10,
|
||||
"name": "검색 결과 데이터 검증",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const rows = document.querySelectorAll('table tbody tr, [role=\"row\"]');\n return 'Search result: ' + rows.length + ' rows';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "검색 초기화",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const selectors = ['input[type=\"search\"]', 'input[placeholder*=\"검색\"]', 'input[placeholder*=\"Search\"]', 'input[role=\"searchbox\"]', '[class*=\"search\"] input'];\n for (const sel of selectors) {\n const el = document.querySelector(sel);\n if (el) {\n const nativeSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.set;\n if (nativeSetter) nativeSetter.call(el, '');\n else el.value = '';\n el.dispatchEvent(new Event('input', { bubbles: true }));\n el.dispatchEvent(new Event('change', { bubbles: true }));\n return 'Search cleared';\n }\n }\n return 'No search input found (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "검색 초기화 결과 대기",
|
||||
"action": "wait",
|
||||
"duration": 1000
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"name": "검색 초기화 및 복원 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const rows = document.querySelectorAll('table tbody tr, [role=\"row\"]');\n return 'Restored: ' + rows.length + ' rows';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"name": "검색 후 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"visible_text:게시판"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"name": "첫 번째 행 클릭",
|
||||
"action": "click_first_row"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "상세 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:게시"]
|
||||
"id": 16,
|
||||
"name": "상세 페이지 로딩 대기",
|
||||
"action": "wait",
|
||||
"duration": 1000
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"id": 17,
|
||||
"name": "상세 페이지 - 콘텐츠 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const inputs = document.querySelectorAll('input:not([type=\"hidden\"]), textarea, select');\n const buttons = document.querySelectorAll('button');\n const hasDetail = inputs.length > 0 || document.body.innerText.includes('상세') || document.body.innerText.includes('수정');\n return hasDetail ? 'Detail page: ' + inputs.length + ' inputs, ' + buttons.length + ' buttons' : 'List page (no detail view)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"name": "상세 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"visible_text:게시"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"name": "모달 닫기",
|
||||
"action": "close_modal_if_open"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"id": 20,
|
||||
"name": "페이지네이션 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const paginationSels = ['[class*=\"pagination\"]', '[class*=\"Pagination\"]', 'nav[aria-label*=\"page\"]', 'button[aria-label*=\"page\"]', '[class*=\"pager\"]'];\n for (const sel of paginationSels) {\n const el = document.querySelector(sel);\n if (el) return 'Pagination found';\n }\n const pageButtons = Array.from(document.querySelectorAll('button')).filter(b => /^\\d+$/.test(b.innerText?.trim()));\n if (pageButtons.length > 0) return 'Page buttons found: ' + pageButtons.length;\n return 'No pagination (ok - may have single page)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body"
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"name": "목록 복귀",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('목록'), a:has-text('목록')"
|
||||
|
||||
@@ -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",
|
||||
@@ -25,59 +32,95 @@
|
||||
"action": "menu_navigate",
|
||||
"level1": "인사관리",
|
||||
"level2": "근태관리",
|
||||
"expected": { "url_contains": "/hr/attendance" }
|
||||
"expected": {
|
||||
"url_contains": "/hr/attendance"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "URL 검증",
|
||||
"action": "verify_url",
|
||||
"expected": {
|
||||
"url_contains": "/hr/attendance-management"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "목업 감지",
|
||||
"action": "verify_not_mockup"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "근태관리 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:근태"]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "UI 요소 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:관리"]
|
||||
"name": "통계 카드 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const cards = document.querySelectorAll('[class*=\"card\"], [class*=\"Card\"], [class*=\"stat\"], [class*=\"Stat\"], [class*=\"summary\"]');\n const texts = Array.from(cards).map(c => c.innerText?.substring(0, 30)).filter(Boolean);\n return texts.length > 0 ? 'Stats: ' + texts.length + ' cards found' : 'No stat cards (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "근태관리 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"visible_text:근태"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "UI 요소 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"visible_text:관리"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "필터/검색 시도",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[type='search'], input[type='date'], input[placeholder*='검색'], input[placeholder*='조회'], [class*='search'] input, [class*='filter'] input"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"id": 8,
|
||||
"name": "대기",
|
||||
"action": "wait",
|
||||
"duration": 1000
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"id": 9,
|
||||
"name": "행 클릭 시도",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr, [role='row']:not(:first-child), [class*='list'] [class*='item']"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"id": 10,
|
||||
"name": "상세 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:근태"]
|
||||
"checks": [
|
||||
"visible_text:근태"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"id": 11,
|
||||
"name": "모달 닫기",
|
||||
"action": "close_modal_if_open"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"id": 12,
|
||||
"name": "페이지네이션 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const paginationSels = ['[class*=\"pagination\"]', '[class*=\"Pagination\"]', 'nav[aria-label*=\"page\"]', 'button[aria-label*=\"page\"]', '[class*=\"pager\"]'];\n for (const sel of paginationSels) {\n const el = document.querySelector(sel);\n if (el) return 'Pagination found';\n }\n const pageButtons = Array.from(document.querySelectorAll('button')).filter(b => /^\\d+$/.test(b.innerText?.trim()));\n if (pageButtons.length > 0) return 'Page buttons found: ' + pageButtons.length;\n return 'No pagination (ok - may have single page)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"name": "최종 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:근태"]
|
||||
"checks": [
|
||||
"visible_text:근태"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -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,11 +34,23 @@
|
||||
"level2": "근태현황",
|
||||
"expected": {
|
||||
"url_contains": "/hr/attendance",
|
||||
"visible": ["근태현황", "출근", "퇴근"]
|
||||
"visible": [
|
||||
"근태현황",
|
||||
"출근",
|
||||
"퇴근"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "URL 검증",
|
||||
"action": "verify_url",
|
||||
"expected": {
|
||||
"url_contains": "/hr/attendance"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
@@ -42,7 +61,13 @@
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"id": 4,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const cards = document.querySelectorAll('[class*=\"card\"], [class*=\"Card\"], [class*=\"stat\"], [class*=\"Stat\"], [class*=\"summary\"]');\n const texts = Array.from(cards).map(c => c.innerText?.substring(0, 30)).filter(Boolean);\n return texts.length > 0 ? 'Stats: ' + texts.length + ' cards found' : 'No stat cards (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "근태 현황 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
@@ -55,7 +80,13 @@
|
||||
"expected": "근태 현황 테이블 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"id": 6,
|
||||
"name": "목록 필터 테스트",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const selects = document.querySelectorAll('select, [role=\"combobox\"], button[class*=\"select\"], button[class*=\"Select\"]');\n if (selects.length > 0) {\n return 'Filters found: ' + selects.length;\n }\n return 'No filter dropdowns (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "오늘 근태 상태 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -65,7 +96,7 @@
|
||||
"expected": "오늘 근태 상태 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"id": 8,
|
||||
"name": "출근 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -74,7 +105,7 @@
|
||||
"expected": "출근 버튼 표시"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"id": 9,
|
||||
"name": "퇴근 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -83,7 +114,7 @@
|
||||
"expected": "퇴근 버튼 표시"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"id": 10,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 기간 필터 - 월 선택",
|
||||
"action": "click_if_exists",
|
||||
@@ -91,7 +122,7 @@
|
||||
"expected": "월 선택 열림"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"id": 11,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 조회 적용",
|
||||
"action": "click_if_exists",
|
||||
@@ -99,7 +130,7 @@
|
||||
"expected": "필터 적용됨"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"id": 12,
|
||||
"phase": "FILTER",
|
||||
"name": "[FILTER] 필터 결과 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -109,7 +140,7 @@
|
||||
"expected": "필터 동작 확인"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"id": 13,
|
||||
"name": "근무 시간 통계 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -119,7 +150,7 @@
|
||||
"expected": "근무 통계 표시"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"id": 14,
|
||||
"name": "지각/조퇴/결근 통계 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -130,7 +161,7 @@
|
||||
"expected": "근태 이상 통계 표시"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"id": 15,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 특정 일자 상세 보기",
|
||||
"action": "click_if_exists",
|
||||
@@ -140,7 +171,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"id": 16,
|
||||
"name": "상세 근태 정보 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
@@ -151,7 +182,7 @@
|
||||
"expected": "상세 근태 정보 표시"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"id": 17,
|
||||
"name": "엑셀 다운로드 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -160,13 +191,19 @@
|
||||
"expected": "엑셀 다운로드 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"id": 18,
|
||||
"name": "인쇄 버튼 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
"인쇄 버튼 존재"
|
||||
],
|
||||
"expected": "인쇄 기능 표시"
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
@@ -195,13 +232,19 @@
|
||||
{
|
||||
"id": 3,
|
||||
"name": "검색/필터",
|
||||
"steps": [7, 8, 9],
|
||||
"steps": [
|
||||
7,
|
||||
8,
|
||||
9
|
||||
],
|
||||
"criteria": "기간 필터 동작"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "목업 페이지 감지",
|
||||
"steps": [2],
|
||||
"steps": [
|
||||
2
|
||||
],
|
||||
"criteria": "근태 현황, 날짜 선택, 출퇴근 버튼 존재"
|
||||
}
|
||||
],
|
||||
|
||||
127
hr-card.json
127
hr-card.json
@@ -3,7 +3,14 @@
|
||||
"name": "카드관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
"captureOn": [
|
||||
"error",
|
||||
"fail",
|
||||
"timeout",
|
||||
"404",
|
||||
"500",
|
||||
"blocked"
|
||||
]
|
||||
},
|
||||
"description": "인사관리 > 카드관리 목록/검색/상세 기능 검증",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
@@ -25,54 +32,136 @@
|
||||
"action": "menu_navigate",
|
||||
"level1": "인사관리",
|
||||
"level2": "카드관리",
|
||||
"expected": { "url_contains": "/hr/card" }
|
||||
"expected": {
|
||||
"url_contains": "/hr/card"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "URL 검증",
|
||||
"action": "verify_url",
|
||||
"expected": {
|
||||
"url_contains": "/hr/card-management"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "목업 감지",
|
||||
"action": "verify_not_mockup"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "카드관리 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:카드"]
|
||||
"id": 4,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const cards = document.querySelectorAll('[class*=\"card\"], [class*=\"Card\"], [class*=\"stat\"], [class*=\"Stat\"], [class*=\"summary\"]');\n const texts = Array.from(cards).map(c => c.innerText?.substring(0, 30)).filter(Boolean);\n return texts.length > 0 ? 'Stats: ' + texts.length + ' cards found' : 'No stat cards (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"id": 5,
|
||||
"name": "카드관리 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"visible_text:카드"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "테이블 확인",
|
||||
"action": "verify_table"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"id": 7,
|
||||
"name": "목록 필터 테스트",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const selects = document.querySelectorAll('select, [role=\"combobox\"], button[class*=\"select\"], button[class*=\"Select\"]');\n if (selects.length > 0) {\n return 'Filters found: ' + selects.length;\n }\n return 'No filter dropdowns (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "검색 기능",
|
||||
"action": "search",
|
||||
"value": "테스트"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "검색 후 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:카드"]
|
||||
"id": 9,
|
||||
"name": "검색 결과 대기",
|
||||
"action": "wait",
|
||||
"duration": 1000
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"id": 10,
|
||||
"name": "검색 결과 데이터 검증",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const rows = document.querySelectorAll('table tbody tr, [role=\"row\"]');\n return 'Search result: ' + rows.length + ' rows';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "검색 초기화",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const selectors = ['input[type=\"search\"]', 'input[placeholder*=\"검색\"]', 'input[placeholder*=\"Search\"]', 'input[role=\"searchbox\"]', '[class*=\"search\"] input'];\n for (const sel of selectors) {\n const el = document.querySelector(sel);\n if (el) {\n const nativeSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.set;\n if (nativeSetter) nativeSetter.call(el, '');\n else el.value = '';\n el.dispatchEvent(new Event('input', { bubbles: true }));\n el.dispatchEvent(new Event('change', { bubbles: true }));\n return 'Search cleared';\n }\n }\n return 'No search input found (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "검색 초기화 결과 대기",
|
||||
"action": "wait",
|
||||
"duration": 1000
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"name": "검색 초기화 및 복원 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const rows = document.querySelectorAll('table tbody tr, [role=\"row\"]');\n return 'Restored: ' + rows.length + ' rows';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"name": "검색 후 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"visible_text:카드"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"name": "첫 번째 행 클릭",
|
||||
"action": "click_first_row"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "상세 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:카드"]
|
||||
"id": 16,
|
||||
"name": "상세 페이지 로딩 대기",
|
||||
"action": "wait",
|
||||
"duration": 1000
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"id": 17,
|
||||
"name": "상세 페이지 - 콘텐츠 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const inputs = document.querySelectorAll('input:not([type=\"hidden\"]), textarea, select');\n const buttons = document.querySelectorAll('button');\n const hasDetail = inputs.length > 0 || document.body.innerText.includes('상세') || document.body.innerText.includes('수정');\n return hasDetail ? 'Detail page: ' + inputs.length + ' inputs, ' + buttons.length + ' buttons' : 'List page (no detail view)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"name": "상세 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"visible_text:카드"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"name": "모달 닫기",
|
||||
"action": "close_modal_if_open"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"id": 20,
|
||||
"name": "페이지네이션 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const paginationSels = ['[class*=\"pagination\"]', '[class*=\"Pagination\"]', 'nav[aria-label*=\"page\"]', 'button[aria-label*=\"page\"]', '[class*=\"pager\"]'];\n for (const sel of paginationSels) {\n const el = document.querySelector(sel);\n if (el) return 'Pagination found';\n }\n const pageButtons = Array.from(document.querySelectorAll('button')).filter(b => /^\\d+$/.test(b.innerText?.trim()));\n if (pageButtons.length > 0) return 'Page buttons found: ' + pageButtons.length;\n return 'No pagination (ok - may have single page)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body"
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"name": "목록 복귀",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('목록'), a:has-text('목록')"
|
||||
|
||||
@@ -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",
|
||||
@@ -25,59 +32,95 @@
|
||||
"action": "menu_navigate",
|
||||
"level1": "인사관리",
|
||||
"level2": "부서관리",
|
||||
"expected": { "url_contains": "/hr/department" }
|
||||
"expected": {
|
||||
"url_contains": "/hr/department"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "URL 검증",
|
||||
"action": "verify_url",
|
||||
"expected": {
|
||||
"url_contains": "/hr/department-management"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "목업 감지",
|
||||
"action": "verify_not_mockup"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "부서관리 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:부서"]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "UI 요소 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:관리"]
|
||||
"name": "통계 카드 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const cards = document.querySelectorAll('[class*=\"card\"], [class*=\"Card\"], [class*=\"stat\"], [class*=\"Stat\"], [class*=\"summary\"]');\n const texts = Array.from(cards).map(c => c.innerText?.substring(0, 30)).filter(Boolean);\n return texts.length > 0 ? 'Stats: ' + texts.length + ' cards found' : 'No stat cards (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "부서관리 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"visible_text:부서"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "UI 요소 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"visible_text:관리"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "검색 입력 시도",
|
||||
"action": "click_if_exists",
|
||||
"target": "input[type='search'], input[placeholder*='검색'], input[placeholder*='조회'], [class*='search'] input"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"id": 8,
|
||||
"name": "대기",
|
||||
"action": "wait",
|
||||
"duration": 1000
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"id": 9,
|
||||
"name": "행 클릭 시도",
|
||||
"action": "click_if_exists",
|
||||
"target": "table tbody tr, [role='row']:not(:first-child), [class*='list'] [class*='item']"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"id": 10,
|
||||
"name": "상세 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:부서"]
|
||||
"checks": [
|
||||
"visible_text:부서"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"id": 11,
|
||||
"name": "모달 닫기",
|
||||
"action": "close_modal_if_open"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"id": 12,
|
||||
"name": "페이지네이션 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const paginationSels = ['[class*=\"pagination\"]', '[class*=\"Pagination\"]', 'nav[aria-label*=\"page\"]', 'button[aria-label*=\"page\"]', '[class*=\"pager\"]'];\n for (const sel of paginationSels) {\n const el = document.querySelector(sel);\n if (el) return 'Pagination found';\n }\n const pageButtons = Array.from(document.querySelectorAll('button')).filter(b => /^\\d+$/.test(b.innerText?.trim()));\n if (pageButtons.length > 0) return 'Page buttons found: ' + pageButtons.length;\n return 'No pagination (ok - may have single page)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"name": "최종 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:부서"]
|
||||
"checks": [
|
||||
"visible_text:부서"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
127
hr-employee.json
127
hr-employee.json
@@ -3,7 +3,14 @@
|
||||
"name": "사원관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
"captureOn": [
|
||||
"error",
|
||||
"fail",
|
||||
"timeout",
|
||||
"404",
|
||||
"500",
|
||||
"blocked"
|
||||
]
|
||||
},
|
||||
"description": "인사관리 > 사원관리 목록/검색/상세 기능 검증",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
@@ -25,54 +32,136 @@
|
||||
"action": "menu_navigate",
|
||||
"level1": "인사관리",
|
||||
"level2": "사원관리",
|
||||
"expected": { "url_contains": "/hr/employee" }
|
||||
"expected": {
|
||||
"url_contains": "/hr/employee"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "URL 검증",
|
||||
"action": "verify_url",
|
||||
"expected": {
|
||||
"url_contains": "/hr/employee-management"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "목업 감지",
|
||||
"action": "verify_not_mockup"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "사원관리 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:사원"]
|
||||
"id": 4,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const cards = document.querySelectorAll('[class*=\"card\"], [class*=\"Card\"], [class*=\"stat\"], [class*=\"Stat\"], [class*=\"summary\"]');\n const texts = Array.from(cards).map(c => c.innerText?.substring(0, 30)).filter(Boolean);\n return texts.length > 0 ? 'Stats: ' + texts.length + ' cards found' : 'No stat cards (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"id": 5,
|
||||
"name": "사원관리 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"visible_text:사원"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "테이블 확인",
|
||||
"action": "verify_table"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"id": 7,
|
||||
"name": "목록 필터 테스트",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const selects = document.querySelectorAll('select, [role=\"combobox\"], button[class*=\"select\"], button[class*=\"Select\"]');\n if (selects.length > 0) {\n return 'Filters found: ' + selects.length;\n }\n return 'No filter dropdowns (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "검색 기능",
|
||||
"action": "search",
|
||||
"value": "테스트"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "검색 후 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:사원"]
|
||||
"id": 9,
|
||||
"name": "검색 결과 대기",
|
||||
"action": "wait",
|
||||
"duration": 1000
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"id": 10,
|
||||
"name": "검색 결과 데이터 검증",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const rows = document.querySelectorAll('table tbody tr, [role=\"row\"]');\n return 'Search result: ' + rows.length + ' rows';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "검색 초기화",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const selectors = ['input[type=\"search\"]', 'input[placeholder*=\"검색\"]', 'input[placeholder*=\"Search\"]', 'input[role=\"searchbox\"]', '[class*=\"search\"] input'];\n for (const sel of selectors) {\n const el = document.querySelector(sel);\n if (el) {\n const nativeSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.set;\n if (nativeSetter) nativeSetter.call(el, '');\n else el.value = '';\n el.dispatchEvent(new Event('input', { bubbles: true }));\n el.dispatchEvent(new Event('change', { bubbles: true }));\n return 'Search cleared';\n }\n }\n return 'No search input found (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "검색 초기화 결과 대기",
|
||||
"action": "wait",
|
||||
"duration": 1000
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"name": "검색 초기화 및 복원 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const rows = document.querySelectorAll('table tbody tr, [role=\"row\"]');\n return 'Restored: ' + rows.length + ' rows';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"name": "검색 후 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"visible_text:사원"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"name": "첫 번째 행 클릭",
|
||||
"action": "click_first_row"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "상세 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:사원"]
|
||||
"id": 16,
|
||||
"name": "상세 페이지 로딩 대기",
|
||||
"action": "wait",
|
||||
"duration": 1000
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"id": 17,
|
||||
"name": "상세 페이지 - 콘텐츠 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const inputs = document.querySelectorAll('input:not([type=\"hidden\"]), textarea, select');\n const buttons = document.querySelectorAll('button');\n const hasDetail = inputs.length > 0 || document.body.innerText.includes('상세') || document.body.innerText.includes('수정');\n return hasDetail ? 'Detail page: ' + inputs.length + ' inputs, ' + buttons.length + ' buttons' : 'List page (no detail view)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"name": "상세 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"visible_text:사원"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"name": "모달 닫기",
|
||||
"action": "close_modal_if_open"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"id": 20,
|
||||
"name": "페이지네이션 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const paginationSels = ['[class*=\"pagination\"]', '[class*=\"Pagination\"]', 'nav[aria-label*=\"page\"]', 'button[aria-label*=\"page\"]', '[class*=\"pager\"]'];\n for (const sel of paginationSels) {\n const el = document.querySelector(sel);\n if (el) return 'Pagination found';\n }\n const pageButtons = Array.from(document.querySelectorAll('button')).filter(b => /^\\d+$/.test(b.innerText?.trim()));\n if (pageButtons.length > 0) return 'Page buttons found: ' + pageButtons.length;\n return 'No pagination (ok - may have single page)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body"
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"name": "목록 복귀",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('목록'), a:has-text('목록')"
|
||||
|
||||
127
hr-salary.json
127
hr-salary.json
@@ -3,7 +3,14 @@
|
||||
"name": "급여관리 테스트",
|
||||
"screenshotPolicy": {
|
||||
"onErrorOnly": true,
|
||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||
"captureOn": [
|
||||
"error",
|
||||
"fail",
|
||||
"timeout",
|
||||
"404",
|
||||
"500",
|
||||
"blocked"
|
||||
]
|
||||
},
|
||||
"description": "인사관리 > 급여관리 목록/검색/상세 기능 검증",
|
||||
"baseUrl": "https://dev.codebridge-x.com",
|
||||
@@ -25,54 +32,136 @@
|
||||
"action": "menu_navigate",
|
||||
"level1": "인사관리",
|
||||
"level2": "급여관리",
|
||||
"expected": { "url_contains": "/hr/salary" }
|
||||
"expected": {
|
||||
"url_contains": "/hr/salary"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "URL 검증",
|
||||
"action": "verify_url",
|
||||
"expected": {
|
||||
"url_contains": "/hr/salary-management"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "목업 감지",
|
||||
"action": "verify_not_mockup"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "급여관리 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:급여"]
|
||||
"id": 4,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const cards = document.querySelectorAll('[class*=\"card\"], [class*=\"Card\"], [class*=\"stat\"], [class*=\"Stat\"], [class*=\"summary\"]');\n const texts = Array.from(cards).map(c => c.innerText?.substring(0, 30)).filter(Boolean);\n return texts.length > 0 ? 'Stats: ' + texts.length + ' cards found' : 'No stat cards (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"id": 5,
|
||||
"name": "급여관리 페이지 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"visible_text:급여"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "테이블 확인",
|
||||
"action": "verify_table"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"id": 7,
|
||||
"name": "목록 필터 테스트",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const selects = document.querySelectorAll('select, [role=\"combobox\"], button[class*=\"select\"], button[class*=\"Select\"]');\n if (selects.length > 0) {\n return 'Filters found: ' + selects.length;\n }\n return 'No filter dropdowns (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "검색 기능",
|
||||
"action": "search",
|
||||
"value": "테스트"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "검색 후 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:급여"]
|
||||
"id": 9,
|
||||
"name": "검색 결과 대기",
|
||||
"action": "wait",
|
||||
"duration": 1000
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"id": 10,
|
||||
"name": "검색 결과 데이터 검증",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const rows = document.querySelectorAll('table tbody tr, [role=\"row\"]');\n return 'Search result: ' + rows.length + ' rows';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "검색 초기화",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const selectors = ['input[type=\"search\"]', 'input[placeholder*=\"검색\"]', 'input[placeholder*=\"Search\"]', 'input[role=\"searchbox\"]', '[class*=\"search\"] input'];\n for (const sel of selectors) {\n const el = document.querySelector(sel);\n if (el) {\n const nativeSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.set;\n if (nativeSetter) nativeSetter.call(el, '');\n else el.value = '';\n el.dispatchEvent(new Event('input', { bubbles: true }));\n el.dispatchEvent(new Event('change', { bubbles: true }));\n return 'Search cleared';\n }\n }\n return 'No search input found (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "검색 초기화 결과 대기",
|
||||
"action": "wait",
|
||||
"duration": 1000
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"name": "검색 초기화 및 복원 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const rows = document.querySelectorAll('table tbody tr, [role=\"row\"]');\n return 'Restored: ' + rows.length + ' rows';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"name": "검색 후 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"visible_text:급여"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"name": "첫 번째 행 클릭",
|
||||
"action": "click_first_row"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "상세 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": ["visible_text:급여"]
|
||||
"id": 16,
|
||||
"name": "상세 페이지 로딩 대기",
|
||||
"action": "wait",
|
||||
"duration": 1000
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"id": 17,
|
||||
"name": "상세 페이지 - 콘텐츠 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const inputs = document.querySelectorAll('input:not([type=\"hidden\"]), textarea, select');\n const buttons = document.querySelectorAll('button');\n const hasDetail = inputs.length > 0 || document.body.innerText.includes('상세') || document.body.innerText.includes('수정');\n return hasDetail ? 'Detail page: ' + inputs.length + ' inputs, ' + buttons.length + ' buttons' : 'List page (no detail view)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"name": "상세 확인",
|
||||
"action": "verify_detail",
|
||||
"checks": [
|
||||
"visible_text:급여"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"name": "모달 닫기",
|
||||
"action": "close_modal_if_open"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"id": 20,
|
||||
"name": "페이지네이션 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const paginationSels = ['[class*=\"pagination\"]', '[class*=\"Pagination\"]', 'nav[aria-label*=\"page\"]', 'button[aria-label*=\"page\"]', '[class*=\"pager\"]'];\n for (const sel of paginationSels) {\n const el = document.querySelector(sel);\n if (el) return 'Pagination found';\n }\n const pageButtons = Array.from(document.querySelectorAll('button')).filter(b => /^\\d+$/.test(b.innerText?.trim()));\n if (pageButtons.length > 0) return 'Page buttons found: ' + pageButtons.length;\n return 'No pagination (ok - may have single page)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body"
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"name": "목록 복귀",
|
||||
"action": "click_if_exists",
|
||||
"target": "button:has-text('목록'), a:has-text('목록')"
|
||||
|
||||
@@ -53,6 +53,14 @@
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "URL 검증",
|
||||
"action": "verify_url",
|
||||
"expected": {
|
||||
"url_contains": "/hr/vacation-management"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||
"action": "verify_not_mockup",
|
||||
"checks": [
|
||||
@@ -63,7 +71,13 @@
|
||||
"expected": "정상 페이지 (목업 아님)"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"id": 4,
|
||||
"name": "통계 카드 확인",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const cards = document.querySelectorAll('[class*=\"card\"], [class*=\"Card\"], [class*=\"stat\"], [class*=\"Stat\"], [class*=\"summary\"]');\n const texts = Array.from(cards).map(c => c.innerText?.substring(0, 30)).filter(Boolean);\n return texts.length > 0 ? 'Stats: ' + texts.length + ' cards found' : 'No stat cards (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "휴가 현황 카드 확인",
|
||||
"action": "verify_elements",
|
||||
"checks": [
|
||||
@@ -74,7 +88,7 @@
|
||||
"expected": "휴가 현황 카드 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"id": 6,
|
||||
"name": "휴가 테이블 구조 확인",
|
||||
"action": "verify_table",
|
||||
"checks": [
|
||||
@@ -87,7 +101,13 @@
|
||||
"expected": "휴가 테이블 컬럼 정상 표시"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"id": 7,
|
||||
"name": "목록 필터 테스트",
|
||||
"action": "evaluate",
|
||||
"script": "(() => {\n const selects = document.querySelectorAll('select, [role=\"combobox\"], button[class*=\"select\"], button[class*=\"Select\"]');\n if (selects.length > 0) {\n return 'Filters found: ' + selects.length;\n }\n return 'No filter dropdowns (ok)';\n })()"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 휴가 신청 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
@@ -98,7 +118,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"id": 9,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 휴가 정보 입력",
|
||||
"action": "click_if_exists",
|
||||
@@ -128,7 +148,7 @@
|
||||
"target": "form, [role='dialog'], .modal"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"id": 10,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 필수 검증 #2: 신청 저장",
|
||||
"action": "click_if_exists",
|
||||
@@ -142,14 +162,23 @@
|
||||
"expected": "휴가 신청 완료"
|
||||
},
|
||||
{
|
||||
"id": "7-modal-close",
|
||||
"id": 11,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 저장 완료 토스트 확인",
|
||||
"action": "verify_toast",
|
||||
"verify": {
|
||||
"contains": "등록|완료|성공|저장"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 모달 닫기 확인",
|
||||
"action": "close_modal_if_open",
|
||||
"expected": "모달 닫힘"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"id": 13,
|
||||
"phase": "CREATE",
|
||||
"name": "[CREATE] 신청 결과 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -164,7 +193,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"id": 14,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 휴가 상세 페이지 진입",
|
||||
"action": "click_if_exists",
|
||||
@@ -179,7 +208,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"id": 15,
|
||||
"phase": "READ",
|
||||
"name": "[READ] 상세 정보 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -193,7 +222,7 @@
|
||||
"expected": "입력한 데이터와 일치"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"id": 16,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 모드 진입",
|
||||
"action": "click_if_exists",
|
||||
@@ -204,7 +233,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"id": 17,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 사유 수정",
|
||||
"action": "click_if_exists",
|
||||
@@ -213,7 +242,7 @@
|
||||
"clear": true
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"id": 18,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 필수 검증 #2: 수정 저장",
|
||||
"action": "click_if_exists",
|
||||
@@ -227,7 +256,16 @@
|
||||
"expected": "수정 완료"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"id": 19,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 완료 토스트 확인",
|
||||
"action": "verify_toast",
|
||||
"verify": {
|
||||
"contains": "수정|완료|성공|저장"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"phase": "UPDATE",
|
||||
"name": "[UPDATE] 수정 결과 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -237,7 +275,7 @@
|
||||
"expected": "수정된 데이터 반영"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"id": 21,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 취소 버튼 클릭",
|
||||
"action": "click_if_exists",
|
||||
@@ -248,7 +286,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"id": 22,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 필수 검증 #6: 취소 확인",
|
||||
"action": "click_if_exists",
|
||||
@@ -261,7 +299,7 @@
|
||||
"expected": "휴가 취소 완료 및 목록 복귀"
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"id": 23,
|
||||
"phase": "DELETE",
|
||||
"name": "[DELETE] 취소 결과 확인",
|
||||
"action": "verify_detail",
|
||||
@@ -272,7 +310,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"id": 24,
|
||||
"phase": "VERIFY",
|
||||
"name": "[VERIFY] 연차 잔여일 확인",
|
||||
"action": "verify_elements",
|
||||
@@ -280,6 +318,12 @@
|
||||
"잔여 연차가 원래 값으로 복원"
|
||||
],
|
||||
"expected": "휴가 취소 후 연차 복원 확인"
|
||||
},
|
||||
{
|
||||
"id": 25,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body"
|
||||
}
|
||||
],
|
||||
"expectedAPIs": [
|
||||
|
||||
@@ -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": "/material/stock-status",
|
||||
"urlPattern": "/material/stock-status|/ko/material/stock-status",
|
||||
"menuHints": ["재고현황", "재고 현황", "자재관리"]
|
||||
"menuHints": [
|
||||
"재고현황",
|
||||
"재고 현황",
|
||||
"자재관리"
|
||||
]
|
||||
},
|
||||
"menuNavigation": {
|
||||
"level1": "자재관리",
|
||||
@@ -41,16 +52,18 @@
|
||||
"expectedUrl": "/material/stock-status"
|
||||
},
|
||||
"timeout": 90000,
|
||||
"tags": ["material", "inventory", "read-only"],
|
||||
|
||||
"tags": [
|
||||
"material",
|
||||
"inventory",
|
||||
"read-only"
|
||||
],
|
||||
"auth": {
|
||||
"username": "TestUser5",
|
||||
"password": "password123!"
|
||||
},
|
||||
|
||||
"steps": [
|
||||
{
|
||||
"id": "step-0",
|
||||
"id": 1,
|
||||
"name": "사이드바 메뉴 전체 펼치기",
|
||||
"description": "모두 펼치기 버튼을 클릭하여 전체 메뉴를 펼친 후 메뉴 탐색 준비",
|
||||
"actions": [
|
||||
@@ -58,16 +71,22 @@
|
||||
"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
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "step-1",
|
||||
"id": 2,
|
||||
"name": "자재관리 메뉴 진입",
|
||||
"description": "자재관리 > 재고현황 메뉴로 이동",
|
||||
"actions": [
|
||||
@@ -78,13 +97,25 @@
|
||||
"scrollStep": 200,
|
||||
"maxAttempts": 5
|
||||
},
|
||||
{ "type": "click_if_exists", "target": "자재관리" },
|
||||
{ "type": "wait", "duration": 500 },
|
||||
{ "type": "click_if_exists", "target": "재고현황" }
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "자재관리"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 500
|
||||
},
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "재고현황"
|
||||
}
|
||||
],
|
||||
"expect": {
|
||||
"url": "/material/stock-status",
|
||||
"visible": ["재고 목록", "엑셀 다운로드"]
|
||||
"visible": [
|
||||
"재고 목록",
|
||||
"엑셀 다운로드"
|
||||
]
|
||||
},
|
||||
"fallback": {
|
||||
"type": "navigate",
|
||||
@@ -92,21 +123,44 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-2",
|
||||
"id": 3,
|
||||
"name": "페이지 구조 확인",
|
||||
"description": "통계 카드와 테이블 구조 확인",
|
||||
"verify": {
|
||||
"visible": ["전체 품목", "정상 재고", "재고 부족", "재고 없음"],
|
||||
"tableColumns": ["번호", "품목코드", "품목명", "품목유형", "단위", "재고량", "안전재고", "LOT", "상태", "위치"]
|
||||
"visible": [
|
||||
"전체 품목",
|
||||
"정상 재고",
|
||||
"재고 부족",
|
||||
"재고 없음"
|
||||
],
|
||||
"tableColumns": [
|
||||
"번호",
|
||||
"품목코드",
|
||||
"품목명",
|
||||
"품목유형",
|
||||
"단위",
|
||||
"재고량",
|
||||
"안전재고",
|
||||
"LOT",
|
||||
"상태",
|
||||
"위치"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-3",
|
||||
"id": 4,
|
||||
"name": "필수 검증 #3: 품목유형 탭 필터 - 원자재",
|
||||
"description": "원자재 탭 클릭하여 필터링 확인",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "원자재", "role": "tab" },
|
||||
{ "type": "wait", "duration": 500 }
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "원자재",
|
||||
"role": "tab"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 500
|
||||
}
|
||||
],
|
||||
"expect": {
|
||||
"tabActive": "원자재",
|
||||
@@ -114,12 +168,19 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-4",
|
||||
"id": 5,
|
||||
"name": "필수 검증 #3: 품목유형 탭 필터 - 부자재",
|
||||
"description": "부자재 탭 클릭하여 필터링 확인",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "부자재", "role": "tab" },
|
||||
{ "type": "wait", "duration": 500 }
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "부자재",
|
||||
"role": "tab"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 500
|
||||
}
|
||||
],
|
||||
"expect": {
|
||||
"tabActive": "부자재",
|
||||
@@ -127,12 +188,19 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-5",
|
||||
"id": 6,
|
||||
"name": "필수 검증 #3: 품목유형 탭 필터 - 소모품",
|
||||
"description": "소모품 탭 클릭하여 필터링 확인",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "소모품", "role": "tab" },
|
||||
{ "type": "wait", "duration": 500 }
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "소모품",
|
||||
"role": "tab"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 500
|
||||
}
|
||||
],
|
||||
"expect": {
|
||||
"tabActive": "소모품",
|
||||
@@ -140,12 +208,19 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-6",
|
||||
"id": 7,
|
||||
"name": "전체 탭으로 복귀",
|
||||
"description": "전체 탭 클릭하여 모든 재고 표시",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "전체", "role": "tab" },
|
||||
{ "type": "wait", "duration": 300 }
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "전체",
|
||||
"role": "tab"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 300
|
||||
}
|
||||
],
|
||||
"expect": {
|
||||
"tabActive": "전체",
|
||||
@@ -153,12 +228,18 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-7",
|
||||
"id": 8,
|
||||
"name": "필수 검증 #1: 엑셀 다운로드",
|
||||
"description": "엑셀 다운로드 버튼 동작 확인",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "엑셀 다운로드" },
|
||||
{ "type": "wait", "duration": 1000 }
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "엑셀 다운로드"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 1000
|
||||
}
|
||||
],
|
||||
"expect": {
|
||||
"downloadTriggered": true,
|
||||
@@ -169,7 +250,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-8",
|
||||
"id": 9,
|
||||
"name": "재고 상세 열기",
|
||||
"description": "재고 항목 클릭하여 상세 보기",
|
||||
"actions": [
|
||||
@@ -180,32 +261,54 @@
|
||||
],
|
||||
"expect": {
|
||||
"pageOrModal": "재고 상세",
|
||||
"visible": ["품목코드", "품목명", "재고량", "LOT"]
|
||||
"visible": [
|
||||
"품목코드",
|
||||
"품목명",
|
||||
"재고량",
|
||||
"LOT"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step-9",
|
||||
"id": 10,
|
||||
"name": "상세 닫기",
|
||||
"description": "ESC 키로 상세 닫기 또는 뒤로가기",
|
||||
"actions": [
|
||||
{ "type": "press", "key": "Escape" },
|
||||
{ "type": "wait", "duration": 300 }
|
||||
{
|
||||
"type": "press",
|
||||
"key": "Escape"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 300
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "step-10",
|
||||
"id": 11,
|
||||
"name": "콘솔 에러 확인",
|
||||
"action": "verify_element",
|
||||
"target": "body"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "페이지네이션 확인",
|
||||
"description": "페이지네이션 동작 확인",
|
||||
"actions": [
|
||||
{ "type": "click_if_exists", "target": "다음" },
|
||||
{ "type": "wait", "duration": 500 }
|
||||
{
|
||||
"type": "click_if_exists",
|
||||
"target": "다음"
|
||||
},
|
||||
{
|
||||
"type": "wait",
|
||||
"duration": 500
|
||||
}
|
||||
],
|
||||
"expect": {
|
||||
"pageChanged": true
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
"assertions": [
|
||||
{
|
||||
"type": "url",
|
||||
@@ -218,7 +321,6 @@
|
||||
"message": "엑셀 다운로드 버튼이 표시되어야 함"
|
||||
}
|
||||
],
|
||||
|
||||
"mandatoryVerifications": {
|
||||
"description": "E2E_TEST_CONFIG.md 기준 필수 검증 항목",
|
||||
"items": [
|
||||
@@ -238,13 +340,33 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"notes": {
|
||||
"testScope": "재고현황 조회 및 필터링, 엑셀 다운로드 테스트",
|
||||
"pageType": "조회 전용 (입고관리에서 재고 증가, 출하관리에서 재고 감소)",
|
||||
"statsCards": ["전체 품목", "정상 재고", "재고 부족", "재고 없음"],
|
||||
"typeTabs": ["전체", "원자재", "부자재", "소모품"],
|
||||
"tableColumns": ["번호", "품목코드", "품목명", "품목유형", "단위", "재고량", "안전재고", "LOT", "상태", "위치"],
|
||||
"statsCards": [
|
||||
"전체 품목",
|
||||
"정상 재고",
|
||||
"재고 부족",
|
||||
"재고 없음"
|
||||
],
|
||||
"typeTabs": [
|
||||
"전체",
|
||||
"원자재",
|
||||
"부자재",
|
||||
"소모품"
|
||||
],
|
||||
"tableColumns": [
|
||||
"번호",
|
||||
"품목코드",
|
||||
"품목명",
|
||||
"품목유형",
|
||||
"단위",
|
||||
"재고량",
|
||||
"안전재고",
|
||||
"LOT",
|
||||
"상태",
|
||||
"위치"
|
||||
],
|
||||
"prerequisites": "로그인된 사용자"
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user