{ "scenarioId": "board-management", "scenarioName": "게시판 관리 (Board Management)", "screenshotPolicy": { "onErrorOnly": true, "captureOn": ["error", "fail", "timeout", "404", "500", "blocked"] }, "description": "게시판 관리 페이지의 전체 기능을 검증하는 E2E 테스트", "url": "https://dev.codebridge-x.com/ko/board/board-management", "menuNavigation": { "level1": "게시판", "level2": "게시판 관리", "expectedUrl": "/ko/board/board-management" }, "menuNavigationEnhanced": { "strategy": "scroll-and-search", "level1": { "text": "게시판", "expandable": true }, "level2": { "text": "게시판 관리", "clickable": true }, "scrollConfig": { "container": ".sidebar-scroll", "scrollStep": 200, "maxScrollAttempts": 5, "scrollDelay": 300 }, "fallbackUrl": "/ko/board/board-management", "expectedUrl": "/ko/board/board-management" }, "expectedAPIs": [ { "method": "GET", "endpoint": "/api/v1/boards/tenant", "description": "테넌트 게시판 목록 조회 (시스템 게시판 제외)" }, { "method": "POST", "endpoint": "/api/v1/boards", "description": "게시판 생성" }, { "method": "PUT", "endpoint": "/api/v1/boards/{id}", "description": "게시판 수정" }, { "method": "DELETE", "endpoint": "/api/v1/boards/{id}", "description": "게시판 삭제 (단건)" }, { "method": "DELETE", "endpoint": "/api/v1/boards/{id}", "description": "게시판 삭제 (일괄 - 여러 번 호출)" } ], "steps": [ { "step": 0, "name": "사이드바 초기화", "description": "메뉴 탐색 전 사이드바를 최상단으로 스크롤하여 초기화", "actions": [ { "type": "evaluate", "script": "document.querySelector('.sidebar-scroll')?.scrollTo({top:0,behavior:'instant'})" }, { "type": "wait", "duration": 500 } ], "expected": { "sidebarScrollTop": 0 }, "verification": [ "사이드바가 최상단으로 스크롤됨" ] }, { "step": 1, "name": "2단계 메뉴 진입: 게시판 > 게시판관리", "description": "게시판 > 게시판관리 메뉴로 이동하여 페이지 로드 확인", "navigationPattern": "scrollAndFind", "actions": [ { "type": "scrollAndFind", "target": "게시판", "container": ".sidebar-scroll", "scrollStep": 200, "maxAttempts": 5 }, { "type": "click", "target": "게시판" }, { "type": "wait", "duration": 500 }, { "type": "scrollAndFind", "target": "게시판 관리", "container": ".sidebar-scroll", "scrollStep": 200, "maxAttempts": 3 }, { "type": "click", "target": "게시판 관리" }, { "type": "wait", "target": "페이지 로드 완료" } ], "fallback": { "type": "directNavigation", "url": "/ko/board/board-management" }, "expected": { "url": "/ko/board/board-management", "pageTitle": "게시판관리" }, "verification": [ "페이지 제목 '게시판관리' 표시", "설명 텍스트 '게시판 목록을 관리합니다' 표시", "헤더에 '게시판 등록' 버튼 존재", "검색 입력 필드 존재 (placeholder: '게시판명, 작성자, 대상 검색...')", "탭 영역 존재 (전체/사용/미사용)", "테이블 컬럼 헤더 존재: No., 대상, 게시판명, 상태, 작성자, 등록일시, 작업" ], "mandatoryCheck": "목업 감지 (#5)", "screenshot": "step1_initial-load.png" }, { "step": 2, "name": "초기 데이터 로드 확인", "action": "verify_data", "verification": [ "테이블에 게시판 목록 표시", "각 행에 체크박스, 번호, 대상, 게시판명, 상태 뱃지, 작성자, 등록일시 표시", "대상: '전사', '부서', '권한' 중 하나", "상태 뱃지: '사용함'(초록색) 또는 '사용안함'(회색)" ], "note": "초기 데이터 개수 기록 (통계 카드 확인용)" }, { "step": 3, "name": "통계 카드 검증", "action": "verify_stats", "verification": [ "전체 탭에 총 게시판 수 표시", "사용 탭에 활성 게시판 수 표시", "미사용 탭에 비활성 게시판 수 표시", "전체 = 사용 + 미사용 합계" ], "note": "통계 수치 기록: 전체 N건, 사용 M건, 미사용 K건" }, { "step": 4, "name": "사용 탭 전환", "action": "click_tab", "target": "사용 탭", "verification": [ "탭 활성화 상태 변경", "테이블에 '사용함' 상태 게시판만 표시", "표시된 게시판 수 = 사용 탭 카운트" ] }, { "step": 5, "name": "미사용 탭 전환", "action": "click_tab", "target": "미사용 탭", "verification": [ "탭 활성화 상태 변경", "테이블에 '사용안함' 상태 게시판만 표시", "표시된 게시판 수 = 미사용 탭 카운트" ] }, { "step": 6, "name": "전체 탭으로 복귀", "action": "click_tab", "target": "전체 탭", "verification": [ "탭 활성화 상태 변경", "모든 게시판 표시 (사용함 + 사용안함)", "표시된 게시판 수 = 전체 탭 카운트" ] }, { "step": 7, "name": "⚠️ 필수 검증: 검색 기능 테스트 - 게시판명", "critical": true, "actions": [ { "type": "capture", "variable": "beforeSearchCount", "selector": "table tbody tr", "extract": "count", "description": "검색 전 행 수 저장" }, { "type": "fill", "target": "검색 입력 필드", "value": "{testData.searchKeyword}", "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" }, "mandatoryCheck": "검색/필터 (#3)" }, { "step": "7-1", "name": "검색 결과 데이터 검증", "critical": true, "description": "검색 결과의 모든 행이 검색어를 포함하는지 확인", "verify": { "allRowsContain": "{testData.searchKeyword}", "columnToCheck": "게시판명" } }, { "step": 8, "name": "검색 초기화", "actions": [ { "type": "clear", "target": "검색 입력 필드" }, { "type": "wait", "duration": 500 }, { "type": "capture", "variable": "afterClearCount", "selector": "table tbody tr", "extract": "count" } ], "verify": { "dataRestored": "afterClearCount should equal beforeSearchCount", "searchFieldEmpty": true } }, { "step": 9, "name": "검색 기능 테스트 - 작성자", "action": "search", "target": "검색 입력 필드", "input": "홍킬동", "verification": [ "검색어 '홍킬동' 입력됨", "작성자가 '홍킬동'인 게시판만 표시" ], "mandatoryCheck": "검색/필터 (#3)" }, { "step": 10, "name": "검색 초기화 (2차)", "action": "clear_search", "verification": [ "검색 필드 비어있음", "전체 게시판 다시 표시" ] }, { "step": 11, "name": "단일 게시판 체크박스 선택", "action": "check_single", "target": "첫 번째 게시판 체크박스", "verification": [ "체크박스 선택됨", "작업 컬럼에 수정, 삭제 버튼 표시", "선택된 항목 없음 표시 사라짐" ] }, { "step": 12, "name": "단일 체크박스 해제", "action": "uncheck_single", "verification": [ "체크박스 해제됨", "작업 컬럼의 수정, 삭제 버튼 숨겨짐" ] }, { "step": 13, "name": "다중 게시판 선택 (3개)", "action": "check_multiple", "target": "첫 3개 게시판 체크박스", "verification": [ "3개 체크박스 모두 선택됨", "각 행의 작업 컬럼에 수정, 삭제 버튼 표시", "상단에 일괄 삭제 버튼 또는 선택 카운트 표시" ] }, { "step": 14, "name": "전체 선택 버튼 테스트", "action": "check_all", "target": "헤더 체크박스", "verification": [ "현재 페이지의 모든 체크박스 선택됨", "모든 행에 수정, 삭제 버튼 표시" ] }, { "step": 15, "name": "전체 선택 해제", "action": "uncheck_all", "target": "헤더 체크박스", "verification": [ "모든 체크박스 해제됨", "모든 작업 버튼 숨겨짐" ] }, { "step": 16, "name": "게시판 상세 모달 열기 (행 클릭)", "action": "click_row", "target": "첫 번째 게시판 행 (체크박스 제외 영역)", "verification": [ "상세 페이지로 이동 또는 모달 표시", "URL 변경 확인: /ko/board/board-management/{id}" ], "note": "상세 페이지 이동 확인" }, { "step": 17, "name": "목록으로 돌아가기", "action": "navigate_back", "verification": [ "게시판 관리 목록 페이지로 복귀", "URL: /ko/board/board-management" ] }, { "step": 18, "name": "게시판 등록 페이지 이동", "action": "click_button", "target": "게시판 등록 버튼", "verification": [ "게시판 등록 페이지로 이동", "URL: /ko/board/board-management?mode=new", "페이지 제목 '게시판 등록' 또는 유사 표시" ] }, { "step": 19, "name": "게시판 등록 폼 검증", "action": "verify_form", "verification": [ "대상 선택 필드 존재 (전사/부서/권한)", "게시판명 입력 필드 존재", "상태 선택 필드 존재 (사용함/사용안함)", "등록/저장 버튼 존재", "취소 버튼 존재" ], "mandatoryCheck": "목업 감지 (#5) - 입력 필드 및 동작 버튼 확인" }, { "step": 20, "name": "게시판 등록 - 필수 데이터 입력", "action": "fill_form", "inputs": [ { "field": "대상", "value": "전사", "type": "combobox" }, { "field": "게시판명", "value": "E2E 테스트 게시판", "type": "textbox" }, { "field": "상태", "value": "사용함", "type": "combobox" } ], "verification": [ "모든 필드 값 입력됨" ] }, { "step": 21, "name": "게시판 등록 실행 (URL 안정성 검증)", "action": "submit_form", "target": "등록/저장 버튼", "verification": [ "**URL 유지 또는 목록으로 이동**: /ko/board/board-management", "**404 에러 없음**: '페이지를 찾을 수 없습니다' 텍스트 없음", "**성공 토스트**: '등록 완료' 또는 '생성되었습니다' 메시지 표시", "목록 페이지에서 신규 게시판 표시 확인" ], "mandatoryCheck": "등록/저장 버튼 (#2) - URL 안정성 검증", "criticalCheck": true, "note": "등록 전 URL 저장 → 등록 후 URL 비교 → 에러 텍스트 스캔 → API 호출 확인" }, { "step": 22, "name": "신규 게시판 목록 확인", "action": "verify_list", "verification": [ "목록에 'E2E 테스트 게시판' 표시", "대상: '전사'", "상태: '사용함' (초록색 뱃지)", "통계 업데이트: 전체 +1, 사용 +1" ] }, { "step": 23, "name": "신규 게시판 선택", "action": "check_single", "target": "'E2E 테스트 게시판' 체크박스", "verification": [ "체크박스 선택됨", "수정, 삭제 버튼 표시" ] }, { "step": 24, "name": "수정 버튼 클릭", "action": "click_button", "target": "수정 버튼", "verification": [ "수정 페이지로 이동", "URL: /ko/board/board-management/{id}?mode=edit", "폼에 기존 데이터 로드됨" ] }, { "step": 25, "name": "게시판 정보 수정", "action": "fill_form", "inputs": [ { "field": "게시판명", "value": "E2E 테스트 게시판 (수정됨)", "type": "textbox" }, { "field": "상태", "value": "사용안함", "type": "combobox" } ], "verification": [ "게시판명 변경됨", "상태 '사용안함'으로 변경됨" ] }, { "step": 26, "name": "수정 저장 (URL 안정성 검증)", "action": "submit_form", "target": "저장 버튼", "verification": [ "**URL 유지 또는 목록으로 이동**: /ko/board/board-management", "**404 에러 없음**: '페이지를 찾을 수 없습니다' 텍스트 없음", "**성공 토스트**: '수정 완료' 또는 '저장되었습니다' 메시지 표시" ], "mandatoryCheck": "등록/저장 버튼 (#2) - URL 안정성 검증", "criticalCheck": true }, { "step": 27, "name": "수정 내용 확인", "action": "verify_list", "verification": [ "게시판명 'E2E 테스트 게시판 (수정됨)' 표시", "상태: '사용안함' (회색 뱃지)", "통계 업데이트: 사용 -1, 미사용 +1" ] }, { "step": 28, "name": "미사용 탭에서 확인", "action": "click_tab", "target": "미사용 탭", "verification": [ "'E2E 테스트 게시판 (수정됨)' 표시", "미사용 탭 카운트 +1" ] }, { "step": 29, "name": "전체 탭으로 복귀", "action": "click_tab", "target": "전체 탭", "verification": [ "모든 게시판 표시" ] }, { "step": 30, "name": "단건 삭제 - 게시판 선택", "action": "check_single", "target": "'E2E 테스트 게시판 (수정됨)' 체크박스", "verification": [ "체크박스 선택됨", "삭제 버튼 표시" ] }, { "step": 31, "name": "단건 삭제 확인 다이얼로그 열기", "action": "click_button", "target": "삭제 버튼", "verification": [ "삭제 확인 다이얼로그 표시", "제목: '게시판 삭제'", "메시지: '\"E2E 테스트 게시판 (수정됨)\" 게시판을 삭제하시겠습니까?'", "경고 텍스트: '삭제된 게시판 정보는 복구할 수 없습니다.'", "취소, 삭제 버튼 존재" ] }, { "step": 32, "name": "단건 삭제 실행 (URL 안정성 검증)", "action": "click_button", "target": "다이얼로그 삭제 버튼", "verification": [ "**URL 유지**: /ko/board/board-management", "**404 에러 없음**", "다이얼로그 자동 닫힘", "목록에서 해당 게시판 사라짐", "통계 업데이트: 전체 -1, 미사용 -1" ], "mandatoryCheck": "등록/저장 버튼 (#2) - URL 안정성 검증", "criticalCheck": true }, { "step": 33, "name": "삭제 확인", "action": "verify_list", "verification": [ "'E2E 테스트 게시판 (수정됨)' 목록에 없음", "통계 수치 정확함" ] }, { "step": 34, "name": "일괄 삭제 테스트 - 새 게시판 3개 등록 준비", "action": "navigate", "target": "/ko/board/board-management?mode=new", "note": "일괄 삭제를 위한 테스트 데이터 생성" }, { "step": 35, "name": "테스트 게시판 1 등록", "action": "fill_and_submit", "inputs": [ { "field": "대상", "value": "전사" }, { "field": "게시판명", "value": "일괄삭제테스트1" }, { "field": "상태", "value": "사용함" } ], "verification": [ "등록 성공", "목록으로 복귀" ], "mandatoryCheck": "등록/저장 버튼 (#2)" }, { "step": 36, "name": "테스트 게시판 2 등록", "action": "fill_and_submit", "inputs": [ { "field": "대상", "value": "전사" }, { "field": "게시판명", "value": "일괄삭제테스트2" }, { "field": "상태", "value": "사용함" } ], "verification": [ "등록 성공", "목록으로 복귀" ], "mandatoryCheck": "등록/저장 버튼 (#2)" }, { "step": 37, "name": "테스트 게시판 3 등록", "action": "fill_and_submit", "inputs": [ { "field": "대상", "value": "전사" }, { "field": "게시판명", "value": "일괄삭제테스트3" }, { "field": "상태", "value": "사용함" } ], "verification": [ "등록 성공", "목록으로 복귀", "통계: 전체 +3, 사용 +3" ], "mandatoryCheck": "등록/저장 버튼 (#2)" }, { "step": 38, "name": "일괄 삭제 - 3개 게시판 선택", "action": "check_multiple", "target": "일괄삭제테스트1, 일괄삭제테스트2, 일괄삭제테스트3 체크박스", "verification": [ "3개 체크박스 모두 선택됨", "선택 카운트 '3개 항목 선택됨' 또는 일괄 삭제 버튼 활성화" ] }, { "step": 39, "name": "일괄 삭제 버튼 클릭", "action": "click_button", "target": "일괄 삭제 버튼", "verification": [ "일괄 삭제 확인 다이얼로그 표시", "메시지: '정말 3건을 삭제하시겠습니까?' 또는 유사 문구" ], "note": "IntegratedListTemplateV2의 onBulkDelete 사용" }, { "step": 40, "name": "일괄 삭제 실행 (URL 안정성 검증)", "action": "click_button", "target": "확인 버튼", "verification": [ "**URL 유지**: /ko/board/board-management", "**404 에러 없음**", "다이얼로그 닫힘", "3개 게시판 모두 목록에서 사라짐", "통계 업데이트: 전체 -3, 사용 -3" ], "mandatoryCheck": "등록/저장 버튼 (#2) - URL 안정성 검증", "criticalCheck": true, "note": "DELETE /api/v1/boards/{id} API 3번 호출 확인" }, { "step": 41, "name": "일괄 삭제 확인", "action": "verify_list", "verification": [ "일괄삭제테스트1, 2, 3 모두 목록에 없음", "통계 수치 원래대로 복귀" ] }, { "step": 42, "name": "페이지네이션 테스트 (조건부)", "action": "verify_pagination", "condition": "총 게시판 수 > 20", "verification": [ "페이지네이션 컨트롤 표시", "현재 페이지: 1", "총 페이지 수 표시", "다음 페이지 버튼 활성화" ], "note": "20개 미만이면 SKIP" }, { "step": 43, "name": "페이지네이션 - 2페이지 이동 (조건부)", "action": "click_button", "target": "다음 페이지 또는 페이지 2", "condition": "총 게시판 수 > 20", "verification": [ "페이지 2로 이동", "URL 쿼리 파라미터 또는 상태 업데이트", "21~40번 게시판 표시" ], "note": "20개 미만이면 SKIP" }, { "step": 44, "name": "페이지네이션 - 1페이지로 복귀 (조건부)", "action": "click_button", "target": "이전 페이지 또는 페이지 1", "condition": "총 게시판 수 > 20", "verification": [ "페이지 1로 복귀", "1~20번 게시판 표시" ], "note": "20개 미만이면 SKIP" }, { "step": 45, "name": "콘솔 로그 확인", "action": "verify_console", "verification": [ "JavaScript 에러 없음", "경고 메시지 확인 및 기록" ], "note": "WARNING 레벨 이상 로그 추출" } ], "testData": { "searchKeyword": "공지", "dateRange": { "startDate": "2025-01-01", "endDate": "2026-01-31" }, "newBoard": { "target": "전사", "boardName": "E2E 테스트 게시판", "status": "사용함" }, "updateBoard": { "boardName": "E2E 테스트 게시판 (수정됨)", "status": "사용안함" }, "bulkTestBoards": [ { "boardName": "일괄삭제테스트1", "target": "전사", "status": "사용함" }, { "boardName": "일괄삭제테스트2", "target": "전사", "status": "사용함" }, { "boardName": "일괄삭제테스트3", "target": "전사", "status": "사용함" } ] }, "criticalChecks": [ { "step": 21, "check": "게시판 등록 시 URL 안정성 및 404 에러 없음" }, { "step": 26, "check": "게시판 수정 시 URL 안정성 및 404 에러 없음" }, { "step": 32, "check": "게시판 삭제 시 URL 안정성 및 404 에러 없음" }, { "step": 40, "check": "일괄 삭제 시 URL 안정성 및 404 에러 없음" } ], "notes": [ "게시판 등록/수정/삭제 시 반드시 URL 안정성 검증 수행", "통계 카드는 모든 작업 후 실시간 업데이트 확인", "일괄 삭제는 deleteBoardsBulk 함수로 각 ID에 대해 DELETE API 순차 호출", "IntegratedListTemplateV2 템플릿 사용으로 반응형 디자인 (데스크톱/모바일)", "페이지네이션은 20개 단위로 동작 (20개 미만 시 미표시)", "검색은 게시판명, 작성자명, 대상명 모두 포함", "시스템 게시판(is_system=true)은 이 페이지에 표시되지 않음 (mng에서 관리)" ] }