- crud-delete-vendor: :has-text() CSS 제거, Format B 변환, CSS 셀렉터로 교체 - inspection-management: L2 메뉴 '검사관리' -> '제품검사관리', Format B 변환 - customer-inquiry: L2 메뉴 '1:1 문의' -> '문의하기', expectedUrl 수정 - attendance-checkin: Format B 변환, 출근하기 -> click_if_exists로 변경 - attendance-management: Format B 변환, combobox 액션 사용, wait_for_modal 추가 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
128 lines
4.7 KiB
JSON
128 lines
4.7 KiB
JSON
{
|
|
"id": "attendance-checkin",
|
|
"name": "근태현황 출퇴근 테스트",
|
|
"screenshotPolicy": {
|
|
"onErrorOnly": true,
|
|
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
|
},
|
|
"description": "위치 정보 권한 허용 후 출근/퇴근 기록을 테스트하는 E2E 테스트",
|
|
"baseUrl": "https://dev.codebridge-x.com",
|
|
"menuNavigation": {
|
|
"level1": "인사관리",
|
|
"level2": "근태현황",
|
|
"expectedUrl": "/hr/attendance",
|
|
"searchWithinParent": true,
|
|
"closeOtherMenus": true
|
|
},
|
|
"auth": {
|
|
"username": "TestUser5",
|
|
"password": "password123!"
|
|
},
|
|
"timeout": 120000,
|
|
"tags": ["hr", "attendance", "geolocation", "checkin", "checkout"],
|
|
"browserConfig": {
|
|
"permissions": {
|
|
"geolocation": {
|
|
"grant": true,
|
|
"mockLocation": {
|
|
"enabled": true,
|
|
"latitude": 37.557358,
|
|
"longitude": 126.864414,
|
|
"accuracy": 100
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"steps": [
|
|
{
|
|
"id": 1,
|
|
"name": "GPS 위치 정보 모킹",
|
|
"action": "evaluate",
|
|
"critical": true,
|
|
"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) => { setTimeout(() => success(mockPosition), 100); }, watchPosition: (success) => { setTimeout(() => success(mockPosition), 100); return 1; }, clearWatch: () => {} }; Object.defineProperty(navigator, 'geolocation', { value: mockGeolocation, writable: false, configurable: true }); return 'GPS mocking complete - coords: 37.557358, 126.864414'; })()"
|
|
},
|
|
{
|
|
"id": 2,
|
|
"name": "메뉴 진입: 인사관리 > 근태현황",
|
|
"action": "menu_navigate",
|
|
"level1": "인사관리",
|
|
"level2": "근태현황",
|
|
"expected": { "url_contains": "/hr/attendance" }
|
|
},
|
|
{
|
|
"id": 3,
|
|
"name": "페이지 로드 대기",
|
|
"action": "wait",
|
|
"timeout": 3000
|
|
},
|
|
{
|
|
"id": 4,
|
|
"name": "URL 검증",
|
|
"action": "verify_url",
|
|
"expected": { "url_contains": "/hr/attendance" }
|
|
},
|
|
{
|
|
"id": 5,
|
|
"name": "404 에러 감지",
|
|
"action": "verify_text",
|
|
"target": "body",
|
|
"not_contains": "404"
|
|
},
|
|
{
|
|
"id": 6,
|
|
"name": "페이지 콘텐츠 확인",
|
|
"action": "verify_element",
|
|
"target": "body",
|
|
"description": "근태현황 페이지가 정상 로드되었는지 확인"
|
|
},
|
|
{
|
|
"id": 7,
|
|
"name": "출퇴근 버튼 확인",
|
|
"action": "evaluate",
|
|
"script": "(() => { const btns = Array.from(document.querySelectorAll('button')); const checkin = btns.find(b => b.innerText?.includes('출근')); const checkout = btns.find(b => b.innerText?.includes('퇴근')); return JSON.stringify({ checkinBtn: checkin ? checkin.innerText.trim() : null, checkoutBtn: checkout ? checkout.innerText.trim() : null, status: checkin ? 'not_checked_in' : (checkout ? 'checked_in' : 'unknown') }); })()"
|
|
},
|
|
{
|
|
"id": 8,
|
|
"name": "출근하기 버튼 클릭 (있는 경우)",
|
|
"action": "click_if_exists",
|
|
"target": "button:has-text('출근')",
|
|
"description": "출근 버튼이 있으면 클릭 (이미 출근한 경우 스킵)"
|
|
},
|
|
{
|
|
"id": 9,
|
|
"name": "출근 결과 대기",
|
|
"action": "wait",
|
|
"timeout": 3000
|
|
},
|
|
{
|
|
"id": 10,
|
|
"name": "출퇴근 상태 확인",
|
|
"action": "evaluate",
|
|
"script": "(() => { const body = document.body.innerText; const hasCheckin = body.includes('출근 완료') || body.includes('출근 시간'); const hasCheckout = body.includes('퇴근') && !body.includes('퇴근 완료'); return JSON.stringify({ checkedIn: hasCheckin, checkoutAvailable: hasCheckout, pageText: body.substring(0, 200) }); })()"
|
|
},
|
|
{
|
|
"id": 11,
|
|
"name": "퇴근하기 버튼 확인",
|
|
"action": "click_if_exists",
|
|
"target": "button:has-text('퇴근')",
|
|
"description": "퇴근 버튼이 있으면 클릭 (선택적)"
|
|
},
|
|
{
|
|
"id": 12,
|
|
"name": "최종 상태 확인",
|
|
"action": "verify_element",
|
|
"target": "body",
|
|
"description": "근태현황 페이지 정상 표시 확인"
|
|
}
|
|
],
|
|
"cleanup": {
|
|
"enabled": false,
|
|
"description": "출퇴근 기록은 삭제하지 않음 (업무 데이터)"
|
|
},
|
|
"notes": {
|
|
"testScope": "위치 권한 허용 -> 근태현황 페이지 이동 -> 출근/퇴근 기록 테스트",
|
|
"antiPattern404": "직접 URL 접근 금지 - 반드시 메뉴 클릭으로 페이지 진입",
|
|
"emptyDataHandling": "출근 버튼이 없을 수 있음 (이미 출근한 상태) - click_if_exists로 처리"
|
|
}
|
|
}
|