{ "id": "notification-settings", "name": "설정 - 알림설정", "screenshotPolicy": { "onErrorOnly": true, "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] }, "description": "알림 설정 관리 기능 테스트 - 카테고리별 마스터 스위치, 개별 알림 스위치, 소리 선택, 이메일 알림 설정", "baseUrl": "https://dev.codebridge-x.com", "url": "/ko/settings/notification-settings", "menuNavigation": { "level1": "설정", "level2": "알림설정", "expectedUrl": "/ko/settings/notification-settings" }, "menuNavigationEnhanced": { "strategy": "scroll-and-search", "sidebarSelector": ".sidebar-scroll, [class*='sidebar'], nav[class*='menu']", "scrollConfig": { "maxScrollAttempts": 5, "scrollAmount": 200, "scrollDelay": 300 }, "level1": { "text": "설정", "selectors": [ "button:has-text('설정')", "[role='button']:has-text('설정')", "a:has-text('설정')", "div[class*='menu-item']:has-text('설정')" ], "searchPattern": "scrollAndFind" }, "level2": { "text": "알림설정", "selectors": [ "a:has-text('알림설정')", "button:has-text('알림설정')", "[role='menuitem']:has-text('알림설정')", "div[class*='submenu'] a:has-text('알림설정')" ], "waitAfterLevel1": 500, "searchPattern": "scrollAndFind" }, "fallbackUrl": "/ko/settings/notification-settings" }, "expectedAPIs": [ { "method": "GET", "path": "/api/v1/settings/notifications", "description": "알림 설정 조회" }, { "method": "PUT", "path": "/api/v1/settings/notifications", "description": "알림 설정 저장" } ], "steps": [ { "id": 0, "name": "사이드바 초기화", "description": "메뉴 탐색 전 사이드바를 최상단으로 스크롤하여 초기화", "actions": [ { "type": "evaluate", "script": "document.querySelector('.sidebar-scroll, [class*=\"sidebar\"], nav[class*=\"menu\"]')?.scrollTo({top: 0, behavior: 'instant'})" }, { "type": "wait", "duration": 500 } ], "expected": { "sidebarScrollPosition": "top" }, "validation": "사이드바 스크롤 초기화" }, { "id": 1, "name": "2단계 메뉴 진입: 설정 > 알림설정", "description": "설정 > 알림설정 메뉴로 이동하여 페이지 로드 확인 (scrollAndFind 패턴 사용)", "navigationPattern": "scrollAndFind", "actions": [ { "type": "scrollAndFind", "target": "설정", "selectors": ["button:has-text('설정')", "[role='button']:has-text('설정')", "a:has-text('설정')"], "scrollContainer": ".sidebar-scroll, [class*='sidebar']", "maxAttempts": 5 }, { "type": "click", "target": "설정" }, { "type": "wait", "duration": 500 }, { "type": "scrollAndFind", "target": "알림설정", "selectors": ["a:has-text('알림설정')", "button:has-text('알림설정')", "[role='menuitem']:has-text('알림설정')"], "scrollContainer": ".sidebar-scroll, [class*='sidebar']", "maxAttempts": 3 }, { "type": "click", "target": "알림설정" }, { "type": "wait", "target": "페이지 로드 완료" } ], "fallback": { "type": "directNavigation", "url": "/ko/settings/notification-settings" }, "expected": { "url": "/ko/settings/notification-settings", "title": "알림설정", "authenticated": true }, "validation": "필수 검증 #5: 목업 페이지 감지" }, { "id": 2, "name": "페이지 제목 확인", "action": "verify", "target": "heading[level=1]", "expected": "알림설정", "validation": "텍스트 일치 확인" }, { "id": 3, "name": "설명 텍스트 확인", "action": "verify", "target": "paragraph", "expected": "알림 설정을 관리합니다.", "validation": "텍스트 일치 확인" }, { "id": 4, "name": "항목 설정 버튼 존재 확인", "action": "verify", "target": "button:has-text('항목 설정')", "expected": "버튼 표시됨", "validation": "UI 요소 존재" }, { "id": 5, "name": "저장 버튼 존재 확인", "action": "verify", "target": "button:has-text('저장')", "expected": "버튼 표시됨", "validation": "UI 요소 존재" }, { "id": 6, "name": "공지 알림 카테고리 확인", "action": "verify", "target": "heading:has-text('공지 알림')", "expected": "카테고리 표시됨", "validation": "카테고리 존재" }, { "id": 7, "name": "공지 알림 마스터 스위치 상태 확인", "action": "verify", "target": "heading:has-text('공지 알림') + switch", "expected": "checked 상태", "validation": "초기 상태: ON" }, { "id": 8, "name": "공지사항 알림 항목 확인", "action": "verify", "target": "text='공지사항 알림'", "expected": "하위 알림 항목 표시됨", "validation": "하위 항목 존재" }, { "id": 9, "name": "이벤트 알림 항목 확인", "action": "verify", "target": "text='이벤트 알림'", "expected": "하위 알림 항목 표시됨", "validation": "하위 항목 존재" }, { "id": 10, "name": "일정 알림 카테고리 확인", "action": "verify", "target": "heading:has-text('일정 알림')", "expected": "카테고리 표시됨", "validation": "카테고리 존재" }, { "id": 11, "name": "일정 알림 마스터 스위치 상태 확인", "action": "verify", "target": "heading:has-text('일정 알림') + switch", "expected": "checked 상태", "validation": "초기 상태: ON" }, { "id": 12, "name": "부가세 신고 알림 항목 확인", "action": "verify", "target": "text='부가세 신고 알림'", "expected": "하위 알림 항목 표시됨", "validation": "하위 항목 존재" }, { "id": 13, "name": "부가세 신고 알림 소리 설정 확인", "action": "verify", "target": "text='부가세 신고 알림' >> .. >> combobox", "expected": "무음", "validation": "초기값 확인" }, { "id": 14, "name": "종합소득세 신고 알림 항목 확인", "action": "verify", "target": "text='종합소득세 신고 알림'", "expected": "하위 알림 항목 표시됨", "validation": "하위 항목 존재" }, { "id": 15, "name": "종합소득세 신고 알림 소리 설정 확인", "action": "verify", "target": "text='종합소득세 신고 알림' >> .. >> combobox", "expected": "SAM 보이스", "validation": "초기값 확인" }, { "id": 16, "name": "거래처 알림 카테고리 확인", "action": "verify", "target": "heading:has-text('거래처 알림')", "expected": "카테고리 표시됨", "validation": "카테고리 존재" }, { "id": 17, "name": "거래처 알림 마스터 스위치 상태 확인", "action": "verify", "target": "heading:has-text('거래처 알림') + switch", "expected": "checked 상태", "validation": "초기 상태: ON" }, { "id": 18, "name": "신규 업체 등록 알림 항목 확인", "action": "verify", "target": "text='신규 업체 등록 알림'", "expected": "하위 알림 항목 표시됨", "validation": "하위 항목 존재" }, { "id": 19, "name": "신용등급 등록 알림 항목 확인", "action": "verify", "target": "text='신용등급 등록 알림'", "expected": "하위 알림 항목 표시됨", "validation": "하위 항목 존재" }, { "id": 20, "name": "근태 알림 카테고리 확인", "action": "verify", "target": "heading:has-text('근태 알림')", "expected": "카테고리 표시됨", "validation": "카테고리 존재" }, { "id": 21, "name": "근태 알림 마스터 스위치 상태 확인", "action": "verify", "target": "heading:has-text('근태 알림') + switch", "expected": "checked 상태", "validation": "초기 상태: ON" }, { "id": 22, "name": "연차 알림 항목 확인", "action": "verify", "target": "text='연차 알림'", "expected": "하위 알림 항목 표시됨", "validation": "하위 항목 존재" }, { "id": 23, "name": "출근 알림 항목 확인", "action": "verify", "target": "text='출근 알림'", "expected": "하위 알림 항목 표시됨", "validation": "하위 항목 존재" }, { "id": 24, "name": "지각 알림 항목 확인", "action": "verify", "target": "text='지각 알림'", "expected": "하위 알림 항목 표시됨", "validation": "하위 항목 존재" }, { "id": 25, "name": "결근 알림 항목 확인", "action": "verify", "target": "text='결근 알림'", "expected": "하위 알림 항목 표시됨", "validation": "하위 항목 존재" }, { "id": 26, "name": "수주/발주 알림 카테고리 확인", "action": "verify", "target": "heading:has-text('수주/발주 알림')", "expected": "카테고리 표시됨", "validation": "카테고리 존재" }, { "id": 27, "name": "수주/발주 알림 마스터 스위치 상태 확인", "action": "verify", "target": "heading:has-text('수주/발주 알림') + switch", "expected": "unchecked 상태", "validation": "초기 상태: OFF" }, { "id": 28, "name": "수주 등록 알림 스위치 disabled 확인", "action": "verify", "target": "text='수주 등록 알림' >> .. >> switch", "expected": "disabled 상태", "validation": "마스터 스위치 OFF 시 하위 항목 disabled" }, { "id": 29, "name": "발주 알림 스위치 disabled 확인", "action": "verify", "target": "text='발주 알림' >> .. >> switch", "expected": "disabled 상태", "validation": "마스터 스위치 OFF 시 하위 항목 disabled" }, { "id": 30, "name": "전자결재 알림 카테고리 확인", "action": "verify", "target": "heading:has-text('전자결재 알림')", "expected": "카테고리 표시됨", "validation": "카테고리 존재" }, { "id": 31, "name": "전자결재 알림 마스터 스위치 상태 확인", "action": "verify", "target": "heading:has-text('전자결재 알림') + switch", "expected": "unchecked 상태", "validation": "초기 상태: OFF" }, { "id": 32, "name": "결재요청 알림 항목 확인", "action": "verify", "target": "text='결재요청 알림'", "expected": "하위 알림 항목 표시됨", "validation": "하위 항목 존재" }, { "id": 33, "name": "기안 > 승인 알림 항목 확인", "action": "verify", "target": "text='기안 > 승인 알림'", "expected": "하위 알림 항목 표시됨", "validation": "하위 항목 존재" }, { "id": 34, "name": "기안 > 반려 알림 항목 확인", "action": "verify", "target": "text='기안 > 반려 알림'", "expected": "하위 알림 항목 표시됨", "validation": "하위 항목 존재" }, { "id": 35, "name": "기안 > 완료 알림 항목 확인", "action": "verify", "target": "text='기안 > 완료 알림'", "expected": "하위 알림 항목 표시됨", "validation": "하위 항목 존재" }, { "id": 36, "name": "생산 알림 카테고리 확인", "action": "verify", "target": "heading:has-text('생산 알림')", "expected": "카테고리 표시됨", "validation": "카테고리 존재" }, { "id": 37, "name": "생산 알림 마스터 스위치 상태 확인", "action": "verify", "target": "heading:has-text('생산 알림') + switch", "expected": "unchecked 상태", "validation": "초기 상태: OFF" }, { "id": 38, "name": "안전재고 알림 항목 확인", "action": "verify", "target": "text='안전재고 알림'", "expected": "하위 알림 항목 표시됨", "validation": "하위 항목 존재" }, { "id": 39, "name": "생산완료 알림 항목 확인", "action": "verify", "target": "text='생산완료 알림'", "expected": "하위 알림 항목 표시됨", "validation": "하위 항목 존재" }, { "id": 40, "name": "마스터 스위치 ON 테스트 - 수주/발주 알림 활성화", "action": "click", "target": "heading:has-text('수주/발주 알림') + switch", "expected": "마스터 스위치가 ON으로 변경됨", "validation": "스위치 상태 변경" }, { "id": 41, "name": "하위 스위치 활성화 확인 - 수주 등록 알림", "action": "verify", "target": "text='수주 등록 알림' >> .. >> switch", "expected": "enabled 상태로 변경됨", "validation": "필수 검증: Conditional Rendering - 마스터 ON 시 하위 활성화" }, { "id": 42, "name": "하위 스위치 활성화 확인 - 발주 알림", "action": "verify", "target": "text='발주 알림' >> .. >> switch", "expected": "enabled 상태로 변경됨", "validation": "필수 검증: Conditional Rendering - 마스터 ON 시 하위 활성화" }, { "id": 43, "name": "하위 알림 스위치 ON - 수주 등록 알림", "action": "click", "target": "text='수주 등록 알림' >> .. >> switch", "expected": "스위치가 ON으로 변경됨", "validation": "개별 알림 활성화" }, { "id": 44, "name": "알림 소리 combobox 활성화 확인", "action": "verify", "target": "text='수주 등록 알림' >> .. >> combobox", "expected": "enabled 상태", "validation": "필수 검증: Conditional Rendering - 알림 ON 시 combobox 활성화" }, { "id": 45, "name": "이메일 checkbox 활성화 확인", "action": "verify", "target": "text='수주 등록 알림' >> .. >> checkbox", "expected": "enabled 상태", "validation": "필수 검증: Conditional Rendering - 알림 ON 시 checkbox 활성화" }, { "id": 46, "name": "소리 테스트 버튼 활성화 확인", "action": "verify", "target": "text='수주 등록 알림' >> .. >> button:has(img)", "expected": "enabled 상태", "validation": "필수 검증: Conditional Rendering - 알림 ON 시 버튼 활성화" }, { "id": 47, "name": "알림 소리 선택 - combobox 클릭", "action": "click", "target": "text='수주 등록 알림' >> .. >> combobox", "expected": "드롭다운 메뉴 표시됨", "validation": "combobox 동작 확인" }, { "id": 48, "name": "알림 소리 옵션 확인 - 기본 알림음", "action": "verify", "target": "option:has-text('기본 알림음')", "expected": "옵션 표시됨", "validation": "combobox 옵션 존재" }, { "id": 49, "name": "알림 소리 옵션 확인 - SAM 보이스", "action": "verify", "target": "option:has-text('SAM 보이스')", "expected": "옵션 표시됨", "validation": "combobox 옵션 존재" }, { "id": 50, "name": "알림 소리 옵션 확인 - 무음", "action": "verify", "target": "option:has-text('무음')", "expected": "옵션 표시됨", "validation": "combobox 옵션 존재" }, { "id": 51, "name": "알림 소리 선택 - SAM 보이스", "action": "click", "target": "option:has-text('SAM 보이스')", "expected": "SAM 보이스 선택됨", "validation": "combobox 값 변경" }, { "id": 52, "name": "선택된 알림 소리 확인", "action": "verify", "target": "text='수주 등록 알림' >> .. >> combobox", "expected": "SAM 보이스", "validation": "combobox 선택값 반영" }, { "id": 53, "name": "이메일 알림 활성화", "action": "click", "target": "text='수주 등록 알림' >> .. >> checkbox", "expected": "checkbox 체크됨", "validation": "checkbox 상태 변경" }, { "id": 54, "name": "이메일 checkbox 상태 확인", "action": "verify", "target": "text='수주 등록 알림' >> .. >> checkbox", "expected": "checked 상태", "validation": "checkbox 선택 반영" }, { "id": 55, "name": "마스터 스위치 ON 테스트 - 전자결재 알림 활성화", "action": "click", "target": "heading:has-text('전자결재 알림') + switch", "expected": "마스터 스위치가 ON으로 변경됨", "validation": "스위치 상태 변경" }, { "id": 56, "name": "전자결재 하위 스위치 활성화 확인 - 결재요청 알림", "action": "verify", "target": "text='결재요청 알림' >> .. >> switch", "expected": "enabled 상태로 변경됨", "validation": "Conditional Rendering - 마스터 ON 시 하위 활성화" }, { "id": 57, "name": "전자결재 하위 스위치 활성화 확인 - 기안 > 승인 알림", "action": "verify", "target": "text='기안 > 승인 알림' >> .. >> switch", "expected": "enabled 상태로 변경됨", "validation": "Conditional Rendering - 마스터 ON 시 하위 활성화" }, { "id": 58, "name": "전자결재 하위 스위치 활성화 확인 - 기안 > 반려 알림", "action": "verify", "target": "text='기안 > 반려 알림' >> .. >> switch", "expected": "enabled 상태로 변경됨", "validation": "Conditional Rendering - 마스터 ON 시 하위 활성화" }, { "id": 59, "name": "전자결재 하위 스위치 활성화 확인 - 기안 > 완료 알림", "action": "verify", "target": "text='기안 > 완료 알림' >> .. >> switch", "expected": "enabled 상태로 변경됨", "validation": "Conditional Rendering - 마스터 ON 시 하위 활성화" }, { "id": 60, "name": "결재요청 알림 스위치 ON", "action": "click", "target": "text='결재요청 알림' >> .. >> switch", "expected": "스위치가 ON으로 변경됨", "validation": "개별 알림 활성화" }, { "id": 61, "name": "결재요청 알림 소리 변경 - combobox 클릭", "action": "click", "target": "text='결재요청 알림' >> .. >> combobox", "expected": "드롭다운 메뉴 표시됨", "validation": "combobox 동작 확인" }, { "id": 62, "name": "결재요청 알림 소리 선택 - 무음", "action": "click", "target": "option:has-text('무음')", "expected": "무음 선택됨", "validation": "combobox 값 변경" }, { "id": 63, "name": "결재요청 알림 이메일 활성화", "action": "click", "target": "text='결재요청 알림' >> .. >> checkbox", "expected": "checkbox 체크됨", "validation": "checkbox 상태 변경" }, { "id": 64, "name": "마스터 스위치 ON 테스트 - 생산 알림 활성화", "action": "click", "target": "heading:has-text('생산 알림') + switch", "expected": "마스터 스위치가 ON으로 변경됨", "validation": "스위치 상태 변경" }, { "id": 65, "name": "생산 하위 스위치 활성화 확인 - 안전재고 알림", "action": "verify", "target": "text='안전재고 알림' >> .. >> switch", "expected": "enabled 상태로 변경됨", "validation": "Conditional Rendering - 마스터 ON 시 하위 활성화" }, { "id": 66, "name": "생산 하위 스위치 활성화 확인 - 생산완료 알림", "action": "verify", "target": "text='생산완료 알림' >> .. >> switch", "expected": "enabled 상태로 변경됨", "validation": "Conditional Rendering - 마스터 ON 시 하위 활성화" }, { "id": 67, "name": "안전재고 알림 스위치 ON", "action": "click", "target": "text='안전재고 알림' >> .. >> switch", "expected": "스위치가 ON으로 변경됨", "validation": "개별 알림 활성화" }, { "id": 68, "name": "저장 버튼 클릭 전 URL 저장", "action": "saveUrl", "target": "currentUrl", "expected": "/settings/notification-settings", "validation": "필수 검증 #2: URL 변경 감지를 위한 저장" }, { "id": 69, "name": "저장 버튼 클릭", "action": "click", "target": "button:has-text('저장')", "expected": "저장 처리 시작", "validation": "필수 검증 #2: 등록/저장 버튼 동작" }, { "id": 70, "name": "저장 후 URL 변경 여부 확인", "action": "verify", "target": "currentUrl", "expected": "/settings/notification-settings (변경 없음)", "validation": "필수 검증 #2: 페이지 이동 없음 확인" }, { "id": 71, "name": "에러 페이지 텍스트 확인", "action": "verify", "target": "body", "expected": "404, Not Found 텍스트 없음", "validation": "필수 검증 #2: 에러 페이지 감지" }, { "id": 72, "name": "성공 토스트 메시지 확인", "action": "wait", "target": "text='알림 설정이 저장되었습니다' or text='저장되었습니다'", "expected": "토스트 메시지 표시됨", "validation": "필수 검증 #2: 성공 토스트 확인" }, { "id": 73, "name": "Network Request 확인 - PUT API", "action": "verifyNetwork", "target": "PUT /api/v1/settings/notifications", "expected": "200 OK", "validation": "필수 검증 #2: API 호출 성공" }, { "id": 74, "name": "페이지 새로고침", "action": "reload", "target": "page", "expected": "페이지 다시 로드됨", "validation": "데이터 지속성 테스트" }, { "id": 75, "name": "페이지 로드 대기", "action": "wait", "target": "heading:has-text('알림설정')", "expected": "페이지 표시됨", "validation": "새로고침 후 로드" }, { "id": 76, "name": "저장된 값 확인 - 수주/발주 알림 마스터 스위치", "action": "verify", "target": "heading:has-text('수주/발주 알림') + switch", "expected": "checked 상태 유지", "validation": "데이터 지속성: 마스터 스위치" }, { "id": 77, "name": "저장된 값 확인 - 수주 등록 알림 스위치", "action": "verify", "target": "text='수주 등록 알림' >> .. >> switch", "expected": "checked 상태 유지", "validation": "데이터 지속성: 하위 스위치" }, { "id": 78, "name": "저장된 값 확인 - 수주 등록 알림 소리", "action": "verify", "target": "text='수주 등록 알림' >> .. >> combobox", "expected": "SAM 보이스", "validation": "데이터 지속성: combobox 값" }, { "id": 79, "name": "저장된 값 확인 - 수주 등록 알림 이메일", "action": "verify", "target": "text='수주 등록 알림' >> .. >> checkbox", "expected": "checked 상태 유지", "validation": "데이터 지속성: checkbox 값" }, { "id": 80, "name": "저장된 값 확인 - 전자결재 알림 마스터 스위치", "action": "verify", "target": "heading:has-text('전자결재 알림') + switch", "expected": "checked 상태 유지", "validation": "데이터 지속성: 마스터 스위치" }, { "id": 81, "name": "저장된 값 확인 - 결재요청 알림 스위치", "action": "verify", "target": "text='결재요청 알림' >> .. >> switch", "expected": "checked 상태 유지", "validation": "데이터 지속성: 하위 스위치" }, { "id": 82, "name": "저장된 값 확인 - 결재요청 알림 소리", "action": "verify", "target": "text='결재요청 알림' >> .. >> combobox", "expected": "무음", "validation": "데이터 지속성: combobox 값" }, { "id": 83, "name": "저장된 값 확인 - 결재요청 알림 이메일", "action": "verify", "target": "text='결재요청 알림' >> .. >> checkbox", "expected": "checked 상태 유지", "validation": "데이터 지속성: checkbox 값" }, { "id": 84, "name": "저장된 값 확인 - 생산 알림 마스터 스위치", "action": "verify", "target": "heading:has-text('생산 알림') + switch", "expected": "checked 상태 유지", "validation": "데이터 지속성: 마스터 스위치" }, { "id": 85, "name": "저장된 값 확인 - 안전재고 알림 스위치", "action": "verify", "target": "text='안전재고 알림' >> .. >> switch", "expected": "checked 상태 유지", "validation": "데이터 지속성: 하위 스위치" }, { "id": 86, "name": "마스터 스위치 OFF 테스트 - 수주/발주 알림 비활성화", "action": "click", "target": "heading:has-text('수주/발주 알림') + switch", "expected": "마스터 스위치가 OFF로 변경됨", "validation": "스위치 상태 변경" }, { "id": 87, "name": "하위 스위치 비활성화 확인 - 수주 등록 알림", "action": "verify", "target": "text='수주 등록 알림' >> .. >> switch", "expected": "disabled 상태로 변경됨", "validation": "필수 검증: Conditional Rendering - 마스터 OFF 시 하위 비활성화" }, { "id": 88, "name": "하위 combobox 비활성화 확인", "action": "verify", "target": "text='수주 등록 알림' >> .. >> combobox", "expected": "disabled 상태로 변경됨", "validation": "필수 검증: Conditional Rendering - 마스터 OFF 시 combobox 비활성화" }, { "id": 89, "name": "하위 checkbox 비활성화 확인", "action": "verify", "target": "text='수주 등록 알림' >> .. >> checkbox", "expected": "disabled 상태로 변경됨", "validation": "필수 검증: Conditional Rendering - 마스터 OFF 시 checkbox 비활성화" }, { "id": 90, "name": "하위 소리 테스트 버튼 비활성화 확인", "action": "verify", "target": "text='수주 등록 알림' >> .. >> button:has(img)", "expected": "disabled 상태로 변경됨", "validation": "필수 검증: Conditional Rendering - 마스터 OFF 시 버튼 비활성화" } ] }