- 시나리오 품질 감사 리포트 추가 (8개 이슈 유형, 68개 시나리오 분석) - CRUD 수정 스크립트 6개 추가 (DELETE/UPDATE/CREATE 액션 정합성 강화) - 최종 테스트 결과: 68/68 (100%) PASS, 19.6분 소요 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
13 KiB
E2E 시나리오 품질 감사 보고서
감사일: 2026-02-11 16:01 대상: 전체 68개 시나리오 JSON 기준 테스트: 2026-02-10_21-41-21 (68/68 PASS, 19.7분) 분석 방법: step-executor.js 핸들러 코드 + 시나리오 JSON 교차 검증
핵심 발견사항 요약
| 이슈 유형 | 심각도 | 해당 시나리오 수 | 영향 |
|---|---|---|---|
| DELETE 미실행 (verify_element만) | 🔴 CRITICAL | ~20개 CRUD 시나리오 | 삭제 기능 전혀 테스트 안됨 |
| UPDATE 값 미입력 (click만, fill 없음) | 🔴 CRITICAL | ~20개 CRUD 시나리오 | 수정 기능 실제 데이터 변경 없음 |
| CREATE 폼 미입력 (hr-vacation 등) | 🟠 SERIOUS | ~3개 시나리오 | 등록 폼에 데이터 입력 안됨 |
| Noop 액션 (screenshot, saveDownloadedFile 등) | 🟠 SERIOUS | 2개 (company-info, approval-box) | 해당 스텝 검증 완전 누락 |
| 무효 셀렉터 (textbox[label='...']) | 🟠 SERIOUS | 1개 (company-info) | 필드 검증 불가 |
| verify_toast 타이밍 문제 | 🟡 MODERATE | ~20개 CRUD 시나리오 | 토스트 미감지로 warn |
| verify_detail checks 불일치 | 🟡 MODERATE | ~20개 CRUD 시나리오 | 상세 검증 실패로 warn |
| 필터 테스트 미동작 | 🟡 MODERATE | ~50개 시나리오 | 개수만 세고 실제 필터 미테스트 |
| 중복 사이드바 탐색 | 🟢 LOW | 2개 (company-info, approval-box) | 불필요한 스텝, 성능 저하 |
이슈 #1: DELETE 미실행 (🔴 CRITICAL)
문제
CRUD 시나리오의 DELETE 단계에서 verify_element을 사용하여 버튼 존재만 확인하고, 실제 클릭하지 않음.
step-executor.js 동작
verify_element(action):
if (el) return pass("Element exists: ...") ← 존재만 확인
return warn("Element not found: ...") ← 없으면 warn
영향받는 시나리오 (공통 패턴)
// 모든 CRUD 시나리오의 DELETE 단계
{
"phase": "DELETE",
"name": "[DELETE] 삭제 버튼 클릭", ← 이름은 "클릭"이지만
"action": "verify_element", ← 실제로는 verify_element (클릭 안함!)
"target": "button:has-text('삭제')"
}
{
"phase": "DELETE",
"name": "[DELETE] 삭제 확인",
"action": "verify_element", ← 확인 다이얼로그도 클릭 안함!
"target": "button:has-text('삭제'), button:has-text('제거')"
}
수정 방안
// 올바른 DELETE 흐름
{
"phase": "DELETE",
"name": "[DELETE] 삭제 버튼 클릭",
"action": "click", ← click으로 변경
"target": "button:has-text('삭제')"
},
{
"phase": "DELETE",
"name": "[DELETE] 삭제 확인 다이얼로그",
"action": "click_dialog_confirm" ← 확인 다이얼로그 클릭
}
해당 시나리오 목록
| 시나리오 | DELETE 스텝 ID |
|---|---|
| accounting-bill | 21, 22 |
| accounting-deposit | 22, 23 |
| accounting-withdrawal | 22, 23 |
| accounting-bad-debt | 22, 23 |
| accounting-client | 22, 23 |
| accounting-expense-forecast | 18, 19 |
| accounting-payment | 18, 19 |
| accounting-purchase | 17, 18 |
| accounting-receivable | 18, 19 |
| accounting-sales | 17, 18 |
| hr-vacation | 22 |
| quality-inspection | 22, 23 |
| material-receiving | 22, 23 |
| sales-quotation | 22, 23 |
| sales-client | 22, 23 |
| item-management | 15, 16 |
| accounting-bank-transaction | 18, 19 |
| accounting-card-history | 18, 19 |
이슈 #2: UPDATE 값 미입력 (🔴 CRITICAL)
문제
UPDATE 단계에서 입력 필드를 click_if_exists로 클릭만 하고, 값을 채우지 않음.
step-executor.js 동작
click_if_exists(action):
const el = findEl(target);
if (el) { el.click(); return pass("Clicked: ..."); }
return warn("Not found: ...");
// ⚠️ action.value가 있어도 무시! fill 핸들러만 value 처리
영향받는 시나리오 패턴
{
"phase": "UPDATE",
"name": "[UPDATE] 메모 수정",
"action": "click_if_exists", ← click만 수행!
"target": "textarea[name*='memo']" ← 클릭은 하지만
// value 속성 없음! → 실제 값 변경 없음
}
수정 방안
{
"phase": "UPDATE",
"name": "[UPDATE] 메모 수정",
"action": "fill", ← fill로 변경
"target": "textarea[name*='memo']",
"value": "E2E 수정된 메모_{timestamp}" ← 값 추가
}
해당 시나리오 (동일 패턴)
accounting-bill(17), accounting-deposit(17,18), accounting-withdrawal(17,18), quality-inspection(17,18), material-receiving(17,18), sales-quotation(17,18), hr-vacation(17), sales-client(17,18), item-management(12,13) 등 ~20개
이슈 #3: CREATE 폼 미입력 (🟠 SERIOUS)
문제 (hr-vacation 대표)
Step 9에서 click_if_exists 액션에 fields 배열이 있지만, click_if_exists 핸들러는 fields를 무시함.
{
"id": 9,
"phase": "CREATE",
"name": "[CREATE] 휴가 정보 입력",
"action": "click_if_exists", ← fill_form이 아닌 click_if_exists!
"fields": [ ← fields 배열은 완전히 무시됨
{"name": "휴가 유형", "type": "select", "value": "연차"},
{"name": "시작일", "type": "date", "value": "2026-02-10"}
],
"target": "form, [role='dialog'], .modal"
}
수정 방안
{
"id": 9,
"phase": "CREATE",
"name": "[CREATE] 휴가 정보 입력",
"action": "fill_form", ← fill_form으로 변경
"fields": [...] ← 이제 정상 처리됨
}
이슈 #4: Noop 액션 (🟠 SERIOUS)
step-executor.js에서 noop 매핑되는 액션들
// 다음 액션 타입들은 모두 noop → 항상 pass("(noop)") 반환
tryAlternativeUrls → noop
ifStillFailed → noop
expectResponse → noop
assertResponse → noop
saveDownloadedFile → noop
verifyDownloadedFile → noop
log → noop
manualVerification → noop
composite → noop
영향받는 시나리오
company-info (Step 4):
checkFor404→ verify_url_stability (타임아웃 후 warn)tryAlternativeUrls→ noop (무조건 pass)ifStillFailed→ noop (무조건 pass)log→ noop (무조건 pass)
approval-box (Step 11-14): PDF 테스트 전체가 noop
- Step 11:
screenshot→ capture (pass, but no actual capture in step-executor context) - Step 12:
expectResponse→ noop,assertResponse→ noop,saveDownloadedFile→ noop - Step 13:
verifyDownloadedFile→ noop - Step 14:
manualVerification→ noop
결과: PDF 다운로드 테스트가 0% 실행됨
이슈 #5: 무효 CSS 셀렉터 (🟠 SERIOUS)
company-info 고유 문제
Steps 9-15에서 사용하는 셀렉터:
textbox[label='회사명'][disabled]
textbox[label='대표자명'][disabled]
textbox[label='업태'][disabled]
textbox[label='업종'][disabled]
textbox[label='주소명'][disabled]
textbox[label='이메일 (아이디)'][disabled]
textbox[label='사업자등록번호'][disabled]
문제: textbox는 CSS 요소가 아님. ARIA role selector([role="textbox"])나 input 사용 필요.
findEl()은 이 셀렉터를 처리 못함 → warn("Element not found")
이슈 #6: verify_toast 타이밍 (🟡 MODERATE)
문제
verify_toast는 500ms만 대기 후 토스트를 찾음. 토스트가 아직 안 나타났거나 이미 사라진 경우 warn.
현재 구현
async verify_toast(action, ctx) {
await sleep(500); // 500ms만 대기
for (const sel of toastSels) {
const el = document.querySelector(sel);
if (el && el.offsetParent !== null) {
return pass(`Toast found: ...`);
}
}
return warn('No toast/notification found'); // → warn
}
영향
모든 CRUD 시나리오의 verify_toast 스텝이 warn 생성 가능
이슈 #7: 필터 테스트 미동작 (🟡 MODERATE)
문제
거의 모든 시나리오의 "목록 필터 테스트" 스텝이 동일한 evaluate 스크립트를 사용:
// 현재: select/combobox 요소 개수만 세기
const selects = document.querySelectorAll('select, [role="combobox"], ...');
return selects.length > 0 ? 'Filters found: ' + selects.length : 'No filter dropdowns (ok)';
결과: 필터 존재 여부만 확인. 실제 필터 열기/선택/결과 변화 미검증.
이슈 #8: 중복 사이드바 탐색 (🟢 LOW)
문제
company-info, approval-box의 Steps 1-4가 사이드바 탐색을 수행하지만,
run-all.js의 navigateViaMenu()가 이미 사이드바 탐색을 처리함.
영향
- 중복 실행으로 시간 낭비 (company-info: 48.5초, approval-box: 46.2초)
- Format B (actions 배열) 사용으로 step-executor에서 warn 발생 다수
시나리오별 상세 분류
🟢 정상 시나리오 (0 warns, 22/22 등)
| 시나리오 | 스텝 | Pass | Pattern |
|---|---|---|---|
| free-board | 22 | 22 | ✅ 모범 패턴 |
| board-management | 22 | 22 | ✅ |
| employee-register | 21 | 21 | ✅ |
| hr-attendance-admin | 14 | 14 | ✅ |
| hr-card | 22 | 22 | ✅ |
| hr-department | 14 | 14 | ✅ |
| hr-employee | 22 | 22 | ✅ |
| hr-salary | 22 | 22 | ✅ |
| inventory-status | 12 | 12 | ✅ |
| quality-certification | 14 | 14 | ✅ |
| vendor-management | 34 | 34 | ✅ |
| withdrawal-management | 21 | 21 | ✅ |
| receiving-management | 9 | 9 | ✅ |
| pdf-download-test | 5 | 5 | ✅ |
🟡 경미한 이슈 (1-4 warns)
| 시나리오 | Total | Pass | Warns | 주요 이슈 |
|---|---|---|---|---|
| login | 24 | 22 | 2 | verify 관련 |
| accounting-bad-debt | 24 | 22 | 2 | verify_toast, verify_detail |
| production-work-order | 25 | 23 | 2 | verify_toast |
| production-dashboard | 12 | 10 | 2 | evaluate 관련 |
| accounting-receivable | 19 | 16 | 3 | CRUD verify |
| department-add | 16 | 13 | 3 | verify 관련 |
| reference-box | 40 | 37 | 3 | verify 관련 |
| settings-company | 16 | 13 | 3 | verify 관련 |
| sales-pricing | 27 | 24 | 3 | CRUD verify |
🟠 심각한 이슈 (5-8 warns)
| 시나리오 | Total | Pass | Warns | 주요 이슈 |
|---|---|---|---|---|
| accounting-bill | 24 | 16 | 8 | DELETE 미실행 + UPDATE 미입력 + verify_toast |
| accounting-deposit | 25 | 17 | 8 | DELETE 미실행 + UPDATE 미입력 |
| accounting-withdrawal | 25 | 17 | 8 | DELETE 미실행 + UPDATE 미입력 |
| material-receiving | 25 | 17 | 8 | DELETE 미실행 + UPDATE 미입력 |
| quality-inspection | 25 | 17 | 8 | DELETE 미실행 + UPDATE 미입력 |
| sales-quotation | 25 | 17 | 8 | DELETE 미실행 + UPDATE 미입력 |
| approval-box | 20 | 12 | 8 | Noop 액션 + 중복 탐색 |
| hr-vacation | 25 | 18 | 7 | CREATE 미입력 + DELETE 미실행 |
| sales-client | 24 | 17 | 7 | DELETE 미실행 + UPDATE 미입력 |
| attendance-checkin | 17 | 12 | 5 | verify 관련 |
| item-management | 16 | 11 | 5 | DELETE 미실행 + UPDATE 미입력 |
| sales-management | 54 | 49 | 5 | verify_toast + verify_detail |
🔴 심각한 이슈 (9+ warns)
| 시나리오 | Total | Pass | Warns | 주요 이슈 |
|---|---|---|---|---|
| company-info | 31 | 14 | 17 | 무효 셀렉터 + noop + 중복 탐색 |
수정 우선순위 권장
Phase 1: CRITICAL (DELETE/UPDATE 실행 안되는 CRUD 시나리오)
~20개 시나리오 일괄 수정 (동일 패턴)
- DELETE 단계:
verify_element→click+click_dialog_confirm - UPDATE 단계:
click_if_exists(input) →fill(with value) - CREATE 단계 (hr-vacation):
click_if_exists→fill_form
Phase 2: SERIOUS (company-info, approval-box 재작성)
- company-info: 무효 셀렉터 교체, 불필요 스텝 제거, Format A 통일
- approval-box: noop 스텝 제거/교체, PDF 테스트 분리
Phase 3: MODERATE (verify_toast, verify_detail 개선)
- verify_toast 대기 시간 조정 (step-executor.js 수정)
- verify_detail checks 텍스트 일치 조건 완화
- 필터 테스트 실제 상호작용 추가
모범 패턴 (free-board 기준)
// ✅ GOOD: Format A, 올바른 액션, 실제 동작
{
"id": 1,
"name": "메뉴 진입",
"action": "menu_navigate", // ← run-all.js가 처리
"level1": "게시판",
"level2": "자유게시판"
},
{
"id": 8,
"name": "검색 기능",
"action": "search", // ← 실제 검색 수행
"value": "테스트"
},
{
"id": 15,
"name": "첫 번째 행 클릭",
"action": "click_first_row" // ← 실제 클릭
},
{
"id": 17,
"name": "상세 콘텐츠 확인",
"action": "evaluate", // ← JS 스크립트로 직접 검증
"script": "(() => { ... })()"
}
결론
표면적 결과: 68/68 PASS (100%) 실질적 검증 수준: 약 60-70% (CRUD DELETE/UPDATE 미실행, noop 스텝 포함)
핵심 문제는 CRUD 시나리오에서 DELETE와 UPDATE가 명목상으로만 테스트되고, 실제로는 존재 확인(verify_element)이나 클릭만(click_if_exists without value) 수행하여 기능 동작을 검증하지 않는다는 것이다.
수정 Phase 1만 완료해도 실질적 검증 수준이 **85-90%**로 개선될 것으로 예상.