{ "id": "popup-management", "name": "설정 - 팝업관리", "screenshotPolicy": { "onErrorOnly": true, "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] }, "description": "팝업 관리 기능 테스트 - 목록 조회, 검색, 등록, 수정, 삭제 기능", "baseUrl": "https://dev.codebridge-x.com", "url": "/ko/settings/popup-management", "navigation": { "targetUrl": "/settings/popup-management", "urlPattern": "/settings/popup-management|/ko/settings/popup-management", "menuHints": ["팝업관리", "팝업 관리", "설정"] }, "menuNavigation": { "level1": "설정", "level2": "팝업관리", "expectedUrl": "/ko/settings/popup-management" }, "menuNavigationEnhanced": { "strategy": "scroll-and-search", "sidebarSelector": ".sidebar-scroll, [data-testid='sidebar'], nav[role='navigation']", "scrollConfig": { "scrollStep": 200, "maxScrollAttempts": 10, "scrollDelay": 300 }, "level1": { "text": "설정", "fallbackSelectors": [ "button:has-text('설정')", "[data-menu='settings']", "a[href*='settings']" ] }, "level2": { "text": "팝업관리", "fallbackSelectors": [ "a:has-text('팝업관리')", "[data-submenu='popup-management']", "a[href*='popup-management']" ] }, "fallbackDirectUrl": "/ko/settings/popup-management" }, "expectedAPIs": [ { "method": "GET", "path": "/api/v1/settings/popups", "description": "팝업 목록 조회" }, { "method": "GET", "path": "/api/v1/settings/popups/:id", "description": "팝업 상세 조회" }, { "method": "POST", "path": "/api/v1/settings/popups", "description": "팝업 등록" }, { "method": "PUT", "path": "/api/v1/settings/popups/:id", "description": "팝업 수정" }, { "method": "DELETE", "path": "/api/v1/settings/popups/:id", "description": "팝업 삭제" } ], "steps": [ { "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 } ], "expected": { "sidebarReady": true }, "validation": ["사이드바 스크롤 초기화"] }, { "step": 1, "name": "2단계 메뉴 진입: 설정 > 팝업관리", "description": "설정 > 팝업관리 메뉴로 이동하여 페이지 로드 확인 (scrollAndFind 패턴 사용)", "navigationPattern": "scrollAndFind", "actions": [ { "type": "scrollAndFind", "target": "설정", "scrollContainer": ".sidebar-scroll, [data-testid='sidebar'], nav[role='navigation']", "scrollStep": 200, "maxAttempts": 10 }, { "type": "click", "target": "설정" }, { "type": "wait", "duration": 500 }, { "type": "scrollAndFind", "target": "팝업관리", "scrollContainer": ".sidebar-scroll, [data-testid='sidebar'], nav[role='navigation']", "scrollStep": 200, "maxAttempts": 5 }, { "type": "click", "target": "팝업관리" }, { "type": "wait", "target": "페이지 로드 완료" } ], "fallback": { "type": "directNavigation", "url": "/ko/settings/popup-management" }, "expected": { "url": "/ko/settings/popup-management", "title": "팝업관리", "authenticated": true }, "validation": ["페이지 제목 확인", "테이블 표시 확인"] }, { "step": 2, "name": "페이지 제목 확인", "action": "verify", "target": "heading '팝업관리'", "expected": "'팝업관리' 제목 표시됨", "validation": ["UI 렌더링"] }, { "step": 3, "name": "페이지 설명 확인", "action": "verify", "target": "paragraph '팝업 목록을 관리합니다.'", "expected": "설명 텍스트 표시됨", "validation": ["UI 렌더링"] }, { "step": 4, "name": "팝업 등록 버튼 확인", "action": "verify", "target": "button '팝업 등록'", "expected": "'팝업 등록' 버튼 표시됨", "validation": ["UI 렌더링"] }, { "step": 5, "name": "검색 입력 필드 확인", "action": "verify", "target": "textbox '제목, 작성자로 검색...'", "expected": "검색 필드 표시됨", "validation": ["UI 렌더링"] }, { "step": 6, "name": "테이블 헤더 확인", "action": "verify", "target": "table headers", "expected": "번호, 대상, 제목, 상태, 작성자, 등록일, 기간 컬럼 표시됨", "validation": ["UI 렌더링"] }, { "step": 7, "name": "테이블 데이터 행 확인", "action": "verify", "target": "table rows", "expected": "8개 데이터 행 표시됨", "validation": ["데이터 로드"] }, { "step": 8, "name": "전체 항목 수 표시 확인", "action": "verify", "target": "text '전체 8개 중 1-8개 표시'", "expected": "전체 항목 수 표시됨", "validation": ["UI 렌더링"] }, { "step": 9, "name": "검색 기능 - 제목으로 검색", "action": "type", "target": "textbox '제목, 작성자로 검색...'", "value": "시스템", "expected": "검색어 입력됨", "validation": ["검색/필터"] }, { "step": 10, "name": "검색 결과 확인", "action": "verify", "target": "table rows", "expected": "'시스템' 키워드 포함 행만 표시됨", "validation": ["검색/필터"] }, { "step": 11, "name": "검색어 초기화", "action": "clear", "target": "textbox '제목, 작성자로 검색...'", "expected": "검색어 지워짐", "validation": ["검색/필터"] }, { "step": 12, "name": "전체 목록 재표시 확인", "action": "verify", "target": "table rows", "expected": "전체 8개 행 다시 표시됨", "validation": ["검색/필터"] }, { "step": 13, "name": "팝업 등록 페이지 이동", "action": "click", "target": "button '팝업 등록'", "expected": "/settings/popup-management?mode=new 페이지로 이동", "validation": ["등록/저장"] }, { "step": 14, "name": "등록 페이지 URL 확인", "action": "verify", "target": "url", "expected": "URL이 /settings/popup-management?mode=new", "validation": ["등록/저장"] }, { "step": 15, "name": "등록 페이지 제목 확인", "action": "verify", "target": "heading '팝업관리 상세'", "expected": "'팝업관리 상세' 제목 표시됨", "validation": ["UI 렌더링"] }, { "step": 16, "name": "팝업 정보 섹션 확인", "action": "verify", "target": "heading '팝업 정보 *'", "expected": "'팝업 정보 *' 섹션 표시됨", "validation": ["UI 렌더링"] }, { "step": 17, "name": "대상 Combobox 확인", "action": "verify", "target": "combobox (대상)", "expected": "대상 선택 combobox 표시됨 (기본값: 전사)", "validation": ["UI 렌더링"] }, { "step": 18, "name": "대상 Combobox 클릭", "action": "click", "target": "combobox (대상)", "expected": "드롭다운 옵션 표시됨", "validation": ["UI 동작"] }, { "step": 19, "name": "대상 옵션 확인", "action": "verify", "target": "combobox options", "expected": "'전사', '부서별' 옵션 표시됨", "validation": ["UI 렌더링"] }, { "step": 20, "name": "대상 '부서별' 선택", "action": "click", "target": "option '부서별'", "expected": "'부서별' 선택됨", "validation": ["UI 동작"] }, { "step": 21, "name": "기간 시작일 필드 확인", "action": "verify", "target": "textbox (기간 시작일)", "expected": "시작일 입력 필드 표시됨 (기본값: 오늘 날짜)", "validation": ["UI 렌더링"] }, { "step": 22, "name": "기간 종료일 필드 확인", "action": "verify", "target": "textbox (기간 종료일)", "expected": "종료일 입력 필드 표시됨 (기본값: 오늘 날짜)", "validation": ["UI 렌더링"] }, { "step": 23, "name": "제목 필드 확인", "action": "verify", "target": "textbox '제목 *'", "expected": "제목 입력 필드 표시됨", "validation": ["UI 렌더링"] }, { "step": 24, "name": "제목 입력", "action": "type", "target": "textbox '제목 *'", "value": "E2E 테스트 팝업", "expected": "제목 입력됨", "validation": ["데이터 입력"] }, { "step": 25, "name": "내용 편집기 확인", "action": "verify", "target": "editor toolbar", "expected": "텍스트 편집 도구 모음 표시됨 (굵게, 기울임, 밑줄, 취소선, 정렬, 리스트, 링크, 이미지)", "validation": ["UI 렌더링"] }, { "step": 26, "name": "내용 입력 영역 확인", "action": "verify", "target": "paragraph '내용을 입력해주세요'", "expected": "내용 입력 영역 표시됨", "validation": ["UI 렌더링"] }, { "step": 27, "name": "내용 입력", "action": "type", "target": "editor content area", "value": "이것은 E2E 테스트용 팝업입니다.", "expected": "내용 입력됨", "validation": ["데이터 입력"] }, { "step": 28, "name": "상태 Radio 버튼 확인", "action": "verify", "target": "radiogroup (상태)", "expected": "'사용안함', '사용함' 라디오 버튼 표시됨", "validation": ["UI 렌더링"] }, { "step": 29, "name": "기본 상태 확인", "action": "verify", "target": "radio '사용안함'", "expected": "'사용안함' 선택됨 (기본값)", "validation": ["UI 렌더링"] }, { "step": 30, "name": "상태 '사용함' 선택", "action": "click", "target": "radio '사용함'", "expected": "'사용함' 선택됨", "validation": ["UI 동작"] }, { "step": 31, "name": "작성자 필드 확인", "action": "verify", "target": "textbox (작성자) [disabled]", "expected": "작성자 필드 표시됨 (비활성화, 자동 설정: 홍길동)", "validation": ["UI 렌더링"] }, { "step": 32, "name": "등록일시 필드 확인", "action": "verify", "target": "textbox (등록일시) [disabled]", "expected": "등록일시 필드 표시됨 (비활성화, 자동 설정)", "validation": ["UI 렌더링"] }, { "step": 33, "name": "취소 버튼 확인", "action": "verify", "target": "button '취소'", "expected": "'취소' 버튼 표시됨", "validation": ["UI 렌더링"] }, { "step": 34, "name": "등록 버튼 확인", "action": "verify", "target": "button '등록'", "expected": "'등록' 버튼 표시됨", "validation": ["UI 렌더링"] }, { "step": 35, "name": "등록 전 URL 저장", "action": "store", "target": "current url", "expected": "URL 저장됨", "validation": ["등록/저장"] }, { "step": 36, "name": "등록 버튼 클릭", "action": "click", "target": "button '등록'", "expected": "팝업 등록 요청 전송", "validation": ["등록/저장"] }, { "step": 37, "name": "등록 후 URL 확인", "action": "verify", "target": "url", "expected": "URL이 /settings/popup-management (목록 페이지로 이동)", "validation": ["등록/저장"] }, { "step": 38, "name": "등록 성공 토스트 확인", "action": "verify", "target": "toast message", "expected": "'팝업이 등록되었습니다' 토스트 표시됨", "validation": ["등록/저장"] }, { "step": 39, "name": "등록 API 호출 확인", "action": "verify", "target": "network request", "expected": "POST /api/v1/settings/popups 호출됨 (200 OK)", "validation": ["등록/저장"] }, { "step": 40, "name": "신규 팝업 목록 확인", "action": "verify", "target": "table rows", "expected": "신규 등록된 팝업이 목록에 표시됨", "validation": ["데이터 지속성"] }, { "step": 41, "name": "첫 번째 팝업 행 클릭", "action": "click", "target": "row (첫 번째 팝업)", "expected": "상세 페이지로 이동", "validation": ["UI 동작"] }, { "step": 42, "name": "상세 페이지 URL 확인", "action": "verify", "target": "url", "expected": "URL이 /settings/popup-management/1", "validation": ["UI 동작"] }, { "step": 43, "name": "상세 페이지 제목 확인", "action": "verify", "target": "heading '팝업관리 상세'", "expected": "'팝업관리 상세' 제목 표시됨", "validation": ["UI 렌더링"] }, { "step": 44, "name": "팝업 정보 섹션 확인", "action": "verify", "target": "heading '팝업 정보'", "expected": "'팝업 정보' 섹션 표시됨", "validation": ["UI 렌더링"] }, { "step": 45, "name": "상태 뱃지 확인", "action": "verify", "target": "badge (상태)", "expected": "'사용함' 뱃지 표시됨", "validation": ["UI 렌더링"] }, { "step": 46, "name": "대상 정보 확인", "action": "verify", "target": "definition (대상)", "expected": "'전사' 표시됨", "validation": ["데이터 로드"] }, { "step": 47, "name": "작성자 정보 확인", "action": "verify", "target": "definition (작성자)", "expected": "작성자명 표시됨", "validation": ["데이터 로드"] }, { "step": 48, "name": "제목 정보 확인", "action": "verify", "target": "definition (제목)", "expected": "'시스템 점검 안내' 표시됨", "validation": ["데이터 로드"] }, { "step": 49, "name": "상태 정보 확인", "action": "verify", "target": "definition (상태)", "expected": "'사용함' 표시됨", "validation": ["데이터 로드"] }, { "step": 50, "name": "기간 정보 확인", "action": "verify", "target": "definition (기간)", "expected": "기간 표시됨 (예: 2025-12-24 ~ 2026-01-08)", "validation": ["데이터 로드"] }, { "step": 51, "name": "등록일시 정보 확인", "action": "verify", "target": "definition (등록일시)", "expected": "등록일 표시됨", "validation": ["데이터 로드"] }, { "step": 52, "name": "내용 정보 확인", "action": "verify", "target": "definition (내용)", "expected": "팝업 내용 표시됨", "validation": ["데이터 로드"] }, { "step": 53, "name": "목록으로 버튼 확인", "action": "verify", "target": "button '목록으로'", "expected": "'목록으로' 버튼 표시됨", "validation": ["UI 렌더링"] }, { "step": 54, "name": "삭제 버튼 확인", "action": "verify", "target": "button '삭제'", "expected": "'삭제' 버튼 표시됨", "validation": ["UI 렌더링"] }, { "step": 55, "name": "수정 버튼 확인", "action": "verify", "target": "button '수정'", "expected": "'수정' 버튼 표시됨", "validation": ["UI 렌더링"] }, { "step": 56, "name": "수정 페이지 이동", "action": "click", "target": "button '수정'", "expected": "/settings/popup-management/1?mode=edit 페이지로 이동", "validation": ["등록/저장"] }, { "step": 57, "name": "수정 페이지 URL 확인", "action": "verify", "target": "url", "expected": "URL이 /settings/popup-management/1?mode=edit", "validation": ["등록/저장"] }, { "step": 58, "name": "수정 페이지 제목 확인", "action": "verify", "target": "heading '팝업관리 상세'", "expected": "'팝업관리 상세' 제목 표시됨", "validation": ["UI 렌더링"] }, { "step": 59, "name": "기존 데이터 로드 확인 - 대상", "action": "verify", "target": "combobox (대상)", "expected": "'전사' 선택되어 있음", "validation": ["데이터 로드"] }, { "step": 60, "name": "기존 데이터 로드 확인 - 제목", "action": "verify", "target": "textbox '제목 *'", "expected": "'시스템 점검 안내' 입력되어 있음", "validation": ["데이터 로드"] }, { "step": 61, "name": "기존 데이터 로드 확인 - 내용", "action": "verify", "target": "editor content area", "expected": "기존 내용 표시됨", "validation": ["데이터 로드"] }, { "step": 62, "name": "기존 데이터 로드 확인 - 상태", "action": "verify", "target": "radio '사용함'", "expected": "'사용함' 선택되어 있음", "validation": ["데이터 로드"] }, { "step": 63, "name": "제목 수정", "action": "clear_and_type", "target": "textbox '제목 *'", "value": "시스템 점검 안내 (수정됨)", "expected": "제목 수정됨", "validation": ["데이터 입력"] }, { "step": 64, "name": "내용 수정", "action": "clear_and_type", "target": "editor content area", "value": "수정된 내용입니다.", "expected": "내용 수정됨", "validation": ["데이터 입력"] }, { "step": 65, "name": "상태 변경 - 사용안함 선택", "action": "click", "target": "radio '사용안함'", "expected": "'사용안함' 선택됨", "validation": ["UI 동작"] }, { "step": 66, "name": "저장 버튼 확인", "action": "verify", "target": "button '저장'", "expected": "'저장' 버튼 표시됨", "validation": ["UI 렌더링"] }, { "step": 67, "name": "저장 전 URL 저장", "action": "store", "target": "current url", "expected": "URL 저장됨", "validation": ["등록/저장"] }, { "step": 68, "name": "저장 버튼 클릭", "action": "click", "target": "button '저장'", "expected": "팝업 수정 요청 전송", "validation": ["등록/저장"] }, { "step": 69, "name": "저장 후 URL 확인", "action": "verify", "target": "url", "expected": "URL이 /settings/popup-management/1 (상세 페이지로 이동)", "validation": ["등록/저장"] }, { "step": 70, "name": "저장 성공 토스트 확인", "action": "verify", "target": "toast message", "expected": "'팝업이 수정되었습니다' 토스트 표시됨", "validation": ["등록/저장"] }, { "step": 71, "name": "수정 API 호출 확인", "action": "verify", "target": "network request", "expected": "PUT /api/v1/settings/popups/1 호출됨 (200 OK)", "validation": ["등록/저장"] }, { "step": 72, "name": "수정된 데이터 확인 - 제목", "action": "verify", "target": "definition (제목)", "expected": "'시스템 점검 안내 (수정됨)' 표시됨", "validation": ["데이터 지속성"] }, { "step": 73, "name": "수정된 데이터 확인 - 내용", "action": "verify", "target": "definition (내용)", "expected": "'수정된 내용입니다.' 표시됨", "validation": ["데이터 지속성"] }, { "step": 74, "name": "수정된 데이터 확인 - 상태", "action": "verify", "target": "definition (상태)", "expected": "'사용안함' 표시됨", "validation": ["데이터 지속성"] }, { "step": 75, "name": "목록으로 이동", "action": "click", "target": "button '목록으로'", "expected": "/settings/popup-management 페이지로 이동", "validation": ["UI 동작"] }, { "step": 76, "name": "목록 페이지 URL 확인", "action": "verify", "target": "url", "expected": "URL이 /settings/popup-management", "validation": ["UI 동작"] }, { "step": 77, "name": "수정된 팝업 목록 확인", "action": "verify", "target": "table rows", "expected": "수정된 팝업 정보가 목록에 반영됨", "validation": ["데이터 지속성"] }, { "step": 78, "name": "페이지 새로고침", "action": "refresh", "target": "page", "expected": "페이지 새로고침됨", "validation": ["데이터 지속성"] }, { "step": 79, "name": "새로고침 후 데이터 유지 확인", "action": "verify", "target": "table rows", "expected": "수정된 데이터가 유지됨", "validation": ["데이터 지속성"] }, { "step": 80, "name": "삭제 테스트 - 팝업 상세 페이지 이동", "action": "click", "target": "row (수정한 팝업)", "expected": "상세 페이지로 이동", "validation": ["삭제 기능"] }, { "step": 81, "name": "삭제 버튼 클릭", "action": "click", "target": "button '삭제'", "expected": "삭제 확인 다이얼로그 표시", "validation": ["삭제 기능"] }, { "step": 82, "name": "삭제 확인 다이얼로그 확인", "action": "verify", "target": "dialog", "expected": "삭제 확인 메시지 표시됨", "validation": ["삭제 기능"] }, { "step": 83, "name": "삭제 확인", "action": "click", "target": "button '확인' (dialog)", "expected": "팝업 삭제 요청 전송", "validation": ["삭제 기능"] }, { "step": 84, "name": "삭제 후 URL 확인", "action": "verify", "target": "url", "expected": "URL이 /settings/popup-management (목록 페이지로 이동)", "validation": ["삭제 기능"] }, { "step": 85, "name": "삭제 성공 토스트 확인", "action": "verify", "target": "toast message", "expected": "'팝업이 삭제되었습니다' 토스트 표시됨", "validation": ["삭제 기능"] }, { "step": 86, "name": "삭제 API 호출 확인", "action": "verify", "target": "network request", "expected": "DELETE /api/v1/settings/popups/:id 호출됨 (200 OK)", "validation": ["삭제 기능"] }, { "step": 87, "name": "삭제된 팝업 목록에서 제거 확인", "action": "verify", "target": "table rows", "expected": "삭제된 팝업이 목록에서 사라짐", "validation": ["삭제 기능"] }, { "step": 88, "name": "전체 항목 수 갱신 확인", "action": "verify", "target": "text (전체 항목 수)", "expected": "전체 항목 수가 1개 감소됨", "validation": ["삭제 기능"] } ] }