skills/peach-e2e-scenario/SKILL.md
E2E 시나리오 생성, 실행, 자동수정을 통합 처리하는 스킬. "시나리오 만들어줘", "시나리오 실행", "e2e 실행", "E2E 돌려", "시나리오 돌려", "시나리오 변환", "녹화 변환", "e2e 변환", "codegen 변환", "e2e 생성", "시나리오 생성", "시나리오 검증" 키워드로 트리거.
npx skillsauth add peachsolution/peach-harness peach-e2e-scenarioInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
시나리오 생성 + 실행 + 자동수정을 하나의 루프로 처리한다. 기존 시나리오 코드 패턴을 참조하고, 필요시 DOM을 실시간 조사하여 시나리오를 작성한다. 실행 실패 시 에러를 분석하고 스크립트를 직접 수정하여 재실행한다.
| 모드 | 트리거 | 동작 |
|------|--------|------|
| auto (기본) | /peach-e2e-scenario [설명] | 생성 + 실행 + 자동수정 루프 |
| create | /peach-e2e-scenario create [설명 or codegen] | 시나리오 생성만 |
| run | /peach-e2e-scenario run [경로 or 번호] | 실행 + 자동수정 루프 |
| 용도 | 도구 |
|------|------|
| 시나리오 실행 | ./e2e.sh run (playwright-cli 기반) |
| 셀렉터 디버깅/DOM 확인 | agent-browser eval (빠름) |
| iframe 디버깅 | ./e2e/pwc.sh eval (fallback) |
| 문법 검증 | node --check |
cd e2e && ./e2e.sh chrome을 우선 사용한다. 직접 실행이 필요하면 반드시 --user-data-dir=$HOME/.chrome-beta-e2e-profile을 포함한다../e2e.sh status로 탭 목록을 확인하고 사용자가 실행 탭을 지정하기 전에는 ./e2e.sh run, agent-browser eval, 탭 전환을 시작하지 않는다.agent-browser 디버깅이 비정상이면 OS 레벨 브라우저 우회(open -a, 다른 브라우저 실행, 다른 프로필 경로 사용)를 하지 않는다.Chrome Beta를 CDP 모드로 실행할 때는 고정 프로필 옵션이 필수다. 프로필 옵션이 빠진 실행은 세션 유지 실패로 간주한다.
cd e2e && ./e2e.sh chrome--remote-debugging-port=9222, --remote-allow-origins=*, --user-data-dir=$HOME/.chrome-beta-e2e-profile, --disable-extensions/usr/bin/open -na "Google Chrome Beta" --args ...open -a "Google Chrome Beta" 단독 실행, --args 없는 open 실행, --user-data-dir 없는 Chrome Beta 실행, 다른 프로필 경로 임의 사용, 기본 Chrome 또는 다른 브라우저 우회cd e2e && ./e2e.sh setup
setup이 모든 환경(Chrome Beta, agent-browser, playwright-cli, CDP 연결)을 자동 체크/설치한다.
CDP 미연결이면 아래 순서로 자동 복구를 먼저 시도한다.
cd e2e && ./e2e.sh chrome & 실행sleep 4 대기cd e2e && ./e2e.sh status 재확인cd e2e && ./e2e.sh chrome 수동 실행을 안내한다
./e2e.sh chrome은 고정 프로필($HOME/.chrome-beta-e2e-profile)로 Chrome Beta를 실행하는 표준 경로다. 이 명령 대신 직접 Chrome을 실행할 때도--user-data-dir옵션을 생략하지 않는다.
cd e2e && ./e2e.sh status
탭 목록을 사용자에게 보여주고 "몇 번 탭에서 실행할까요?" 확인.
탭 번호는 0번부터 시작.
chrome://탭은 제외.[번호]가--tab N의 N과 동일. 사용자가 로그인한 탭을 그대로 사용. 환경(local/test/prod) 구분 없음. 탭 번호를 받기 전에는 실행하지 않는다. 민감 세션 작업은 탭 번호를 받아도 사용자 승인 전까지 분석만 수행한다. 탭 드리프트 방지: 사용자가 탭 번호를 응답한 뒤agent-browser tab N직후agent-browser eval "document.title + ' | ' + location.href"로 탭이 맞는지 재검증한다. 예상과 다르면./e2e.sh status재출력 후 재선택. 디버깅/재현 시에는E2E_TAB_ID고정 권장. (상세:peach-e2e-browse/references/탭-선택-패턴.md)
파일 업로드 시나리오: 시나리오 코드에서
page.setInputFiles()또는 file input 조작이 필요하면 OS 네이티브 파일 다이얼로그 차단을 위해Page.setInterceptFileChooserDialog방식을 사용한다. CDP Escape /agent-browser press Escape로는 macOS 네이티브 다이얼로그를 닫을 수 없다. (상세:peach-e2e-browse/references/SPA-프레임워크-입력패턴.md §3)
e2e/시나리오/ 하위 기존 코드를 읽어 패턴 파악
references/시나리오-생성-패턴.md 참조references/코드패턴.md 참조하여 스크립트 작성
references/변환규칙.md 추가 참조references/프레임워크-대응.md 참조NN-), 이 시나리오가 남기는 state 계약, 이 시나리오가 요구하는 선행 state 계약node --check 통과 확인./e2e.sh run 실행 전 반드시 사용자에게 실제 실행 승인을 다시 확인./e2e.sh run --tab N 시나리오/경로references/시나리오-생성-패턴.md + references/코드패턴.md 참조references/변환규칙.md + references/코드패턴.md 참조NN-), 이 시나리오가 남기는 state 계약, 이 시나리오가 요구하는 선행 state 계약chromium.launch() → connect() (lib/connect.js 사용)page.goto('/path') → 현재 탭 상태 확인 후 조건부 이동
page.goto()browser.close() / context.close() 제거page.pause() 제거setDialogHandler 교체 + finally에서 원복 필수)process.exit(0) 고정 종료 금지)waitForTimeout 최소화 → 조건 대기로 변환waitForEvent('popup')) → 닫힘 감지는 waitForEvent('close') 사용node --check 통과 확인e2e/시나리오/{한글카테고리}/{NN}-{시나리오명}.js
cd e2e && ./e2e.sh list
cd e2e && ./e2e.sh run --tab N 시나리오/경로
시나리오 실행 결과가 ❌ 에러:이면 스크립트를 직접 수정하여 재실행한다.
단순 디버깅 안내에 그치지 않고, 원인을 파악하여 시나리오 파일을 고친 뒤 다시 실행하는 것까지가 이 스킬의 책임이다.
자동수정 중 셀렉터/DOM/프레임워크 상호작용 문제가 의심되면
peach-e2e-browse의 의사결정 트리를 적용해 현재 탭에서 DOM과 상호작용 방식을 재확인한다.
확인한 셀렉터와 이벤트 패턴을 시나리오 코드에 반영한 뒤 재실행한다.
상세: references/자동수정-판단트리.md 참조
| 에러 유형 | 처리 방법 |
|-----------|----------|
| 셀렉터 불일치 (timeout, locator not found) | agent-browser eval로 실제 DOM 확인 → 시나리오 셀렉터 수정 |
| dialog 자동 닫힘 (기록하지 못했습니다, dismiss) | daemon 잔류 확인 후 kill → setDialogHandler 패턴 미적용이면 수정 |
| popup waitForEvent('close') 에러 | Promise.race + .catch(() => {}) 패턴 적용 |
| URL 패턴 불일치 (waitForURL timeout) | 실제 이동 URL 확인 → 패턴 수정 |
| 타이밍 문제 (waitForTimeout 후 즉시 실패) | 고정 대기 → waitForEvent 또는 waitForFunction 이벤트 기반으로 교체 |
| Target page, context or browser has been closed | 팝업/탭이 예상보다 일찍 닫힘 → .catch(() => {}) 또는 closeTarget 옵션 추가 |
| navigation timeout (AJAX submit) | waitForNavigation 제거 또는 waitForURL로 교체 |
| 서버 에러 (500, 네트워크 에러) | 자동수정 불가 → 사용자에게 보고 후 중단 |
1. 에러 메시지 파싱 → 유형 판별
2. agent-browser eval로 실제 DOM/URL 확인
3. 시나리오 스크립트 수정
4. 재실행
5. 여전히 실패? → 1로 돌아감 (최대 3회)
6. 3회 실패 → 진단 패키지 출력 → 사용자에게 보고 → peach-e2e-browse 안내
자동수정 3회가 모두 실패하면 anchoring(누적 오답 편향) 위험이 커진다. 같은 컨텍스트에서 무리하게 4회·5회로 늘리지 말고, 새 대화창에서 깨끗한 컨텍스트로 디버깅할 수 있도록 진단 패키지를 구조화하여 출력한다.
🩺 자동수정 3회 실패 — 진단 패키지
## 시나리오
- 파일: <시나리오 파일 절대경로>
- 대상 URL: <실행 대상 URL>
- 탭 ID: <E2E_TAB_ID>
## 시도 이력 (3회)
| 회차 | 추정 원인 | 적용한 수정 | 재실행 결과 |
|------|----------|------------|-----------|
| 1 | <유형> | <변경 요약> | <에러 메시지 첫 줄> |
| 2 | <유형> | <변경 요약> | <에러 메시지 첫 줄> |
| 3 | <유형> | <변경 요약> | <에러 메시지 첫 줄> |
## 마지막 실패 컨텍스트
- 마지막 에러 메시지 (전문)
- 실패 시점 DOM 스냅샷 또는 셀렉터 평가 결과
- 실패 시점 URL
## 추정 막힌 지점
<3회 모두 같은 유형이면 그 유형, 다르면 "다중 원인 의심" 명시>
## 사용자 다음 액션 가이드
1. 새 대화창에서 위 패키지를 첨부하여 디버깅 진행
2. peach-e2e-browse로 현재 탭 상태 직접 확인
3. 시나리오 의도 자체 재검토 필요 가능성
E2E_TAB_ID=<id> ./e2e.sh run '시나리오/대상.js'
dialog 관련 오류라면 실행 전 반드시 daemon 잔류 확인:
lsof -iTCP:9222 -sTCP:ESTABLISHED -n -P | awk '/node/{print $2}' | xargs kill -9 2>/dev/null
# CDP 연결 (1회)
agent-browser connect 9222
# 현재 URL 확인
agent-browser eval "location.href"
# 셀렉터 존재 여부
agent-browser eval "document.querySelector('.target') !== null"
# 버튼 목록
agent-browser eval "JSON.stringify(Array.from(document.querySelectorAll('button')).map(function(b){return b.innerText}))"
# 요소 개수
agent-browser eval "document.querySelectorAll('tr').length"
iframe 내부 디버깅은 agent-browser로 불가 → playwright-cli fallback:
./e2e/pwc.sh eval "document.querySelector('iframe[src*=target]').contentDocument.querySelector('#element').innerText"
window.alert/confirm JS monkey-patch는 동작하지 않는다 — Playwright CDP 자동 dismiss가 먼저 실행됨. 사용 금지.page.on('dialog', handler)) 사용.connect.js의 setDialogHandler(page, prevHandler, newHandler) 유틸로 handler를 교체하고, finally에서 반드시 복원.
다중 page.on('dialog') 등록 시 모두 실행되어 충돌("already handled") 발생 — 교체 패턴 필수.waitForEvent('popup'))은 connect.js를 거치지 않으므로 별도 handler 등록 필요.process.exit(0) 고정 종료 금지 → try/catch/finally + exitCode 패턴 사용.waitForTimeout 대신 page.waitForEvent('dialog') 이벤트 기반 사용.상세: peach-e2e-browse/references/native-dialog-주의사항.md 참조
외부 사이트(Google, Gmail 등) 진입은 load + 2초 지연 + 직접 이동 fallback 패턴 사용.
상세: peach-e2e-browse/references/외부서비스-링크전환-패턴.md 참조
--tab N (빠른 실행용)E2E_TAB_ID 우선 (인덱스 드리프트 방지)# targetId 조회
curl -s http://127.0.0.1:9222/json | jq -r '.[] | select(.type=="page" and (.url|startswith("chrome")|not)) | [.id,.title,.url] | @tsv'
# targetId로 실행
cd e2e && E2E_TAB_ID=<targetId> ./e2e.sh run '시나리오/대상.js'
상세: peach-e2e-browse/references/탭-선택-패턴.md 참조
같은 흐름이 단위에서 반복되면 통합 suite 조합으로 표현한다.
단위 시나리오는 suite에서 조합 가능한 재활용 부품이다. 다음 원칙을 따른다.
단위 시나리오는 다음 기준으로 나눈다.
저장 경로는 e2e/시나리오/{한글카테고리}/{NN}-{시나리오명}.js 형식을 따른다.
상세: peach-e2e-suite/references/suite-scenario-파일구조.md 참조
모든 시나리오 파일 최상단에 E2E_BASE 환경변수 패턴을 사용한다. 도메인 하드코딩은 다중 환경 실행을 차단하는 안티패턴이다.
// 시나리오 파일 최상단 필수
const BASE = process.env.E2E_BASE || 'http://local.example.com';
실행 시:
# 로컬 (기본값)
./e2e.sh run --tab N 시나리오/경로.js
# 개발서버 지정
E2E_BASE=https://dev.example.com ./e2e.sh run --tab N 시나리오/경로.js
시나리오 .js 파일은 UI 조작과 UI 결과 검증만 담당한다. DB 접속 자체가 구조적으로 불가능하므로 시나리오 안에서는 읽기·쓰기 모두 시도하지 않는다.
mysql, dbQuery 등) require 자체가 ENOENT로 실패한다. DB 접속 정보가 시나리오에 들어가면 환경 이식성도 0이 된다.peach-db-query 스킬, 관리자 화면 액션, TDD API)으로 분리한다.| 목적 | 시나리오 안 시도 (불가) | 우회 경로 |
|------|---------------------|---------|
| PK 추출 | SELECT pk FROM table WHERE name='...' | 관리자 list DOM input.pk_check[request_name] 속성 |
| 저장 검증 | SELECT column FROM table WHERE pk=N | 화면 reload 후 입력 요소 .value 확인 |
| DB 사전조건 | INSERT INTO ... | suite fixture Step 또는 peach-db-query 스킬 |
| 상태 강제 전환 | UPDATE ... SET status=... | suite fixture Step 또는 관리자 화면 액션을 시나리오에 추가 |
| 잔존 데이터 정리 | DELETE FROM ... | suite fixture Step 또는 hardDelete TDD API 호출 |
| DB 정합성 확인 | — | suite MD "DB 검증 (선택)" 섹션 + peach-db-query 스킬 (SELECT) |
등록 후 PK를 관리자 list DOM에서 추출하는 표준 패턴:
await page.evaluate((name) => { $('#page_keyword').val(name); searchFormSubmit(); }, TEST_NAME);
await page.waitForTimeout(1500);
const N = await page.evaluate((name) => {
const el = document.getElementById('list_inner_html') || document.body;
const cb = el.querySelector(`input.pk_check[request_name="${name}"]`);
return cb ? parseInt(cb.value, 10) : null;
}, TEST_NAME);
if (!N || N <= 0) throw new Error('PK 추출 실패');
전제: 관리자 list에 input.pk_check 체크박스가 있고, request_name 속성에 이름, value에 PK가 있어야 함.
lib/connect.js의 connect() 함수 사용node — bun은 CDP WebSocket 연결 불가click() 한 줄이 아닌 fallback URL 도달 규칙 적용node --check로 문법 검증 필수| 문서 | 용도 | 로드 조건 |
|------|------|-----------|
| references/코드패턴.md | 시나리오 기본 구조 (IIFE, exitCode, 이모지) | create, auto |
| references/변환규칙.md | codegen → CDP 변환 규칙 | codegen 입력 시 |
| references/프레임워크-대응.md | 레거시/모던 프레임워크 분기 | create, auto |
| references/시나리오-생성-패턴.md | 기존 코드 참조 기반 생성 가이드 | create, auto |
| references/validation-통과-패턴.md | form validation 우회 패턴 | create, auto |
| references/자동수정-판단트리.md | 에러 유형별 자동수정 전략 | run, auto 실패 시 |
| references/daemon-잔류-대응.md | CDP daemon 문제 해결 | dialog 에러 시 |
| references/dialog-handler-패턴.md | native dialog 처리 메커니즘 | dialog 시나리오 |
tools
기능 브랜치용 git worktree 라이프사이클을 관리하는 스킬. 생성(create) / 상태 진단(status) / PR 준비(finish) / 병합 후 정리(closeout) / 정리(cleanup) 모드를 자동 판단한다. "워크트리 만들어줘", "worktree 생성", "워크트리 정리", "워크트리 삭제", "기능 브랜치 워크트리", "워크트리 상태", "마무리", "PR 생성", "PR 머지 후 정리", "feature worktree" 키워드로 트리거. PR 전 base 비교와 안전한 동기화 필요 여부를 진단한다. 개발 완료 후 finish/closeout 모드에서는 한 번의 통합 체크포인트로 push/PR/merge/cleanup을 안전하게 진행한다.
development
Karpathy LLM Wiki 패턴 기반 지식 관리 스킬. 코드 프로젝트와 옵시디언 노트 모두 지원. Raw Source(코드·문서)를 읽어 docs/wiki/에 누적형 지식베이스를 구축·유지한다. "wiki", "위키", "ingest", "인제스트", "wiki 점검", "wiki lint", "wiki 업데이트", "문서화해줘", "아키텍처 설명해줘", "어떻게 동작해?" 키워드로 트리거. qmd 검색 도구와 연동하여 토큰 절약 + 높은 검색 정확도 제공.
development
Backend 없이 Mock 데이터 기반 프로토타입 UI를 생성·검증하는 기획 구체화 산출물 스킬. Vue 3 + TypeScript + NuxtUI v4. 별도 ui-proto 저장소(예: peach-ui-proto-backoffice)의 src/modules-task 폴더에 태스크별 화면을 누적한다. "프로토타입 만들어줘", "Mock 화면", "proto UI", "기획 화면 빠르게", "ui-proto 작업", "기획자 검토용 화면", "태스크 폴더 추가", "팀 ui-proto" 키워드로 트리거. 기획자가 직접 작업하는 화면 기획 + 현업 검토용 산출물 스킬이며, 개발용 Spec은 후속 peach-gen-spec이 생성한다. 실제 API 연동이 필요하면 peach-gen-ui를 사용한다.
development
Spec 필수 + ui-proto 보조 기준으로 E2E 환경 세팅 + 단위 시나리오 자동 분할 + 통합 suite 생성 + 실행 + 부합 검증을 한 번에 처리하는 통합 팀 스킬. "e2e 검증해줘", "통합 검증", "전체 흐름 테스트", "팀 e2e", "스펙대로 동작하는지 확인", "ui-proto와 다른지 확인", "최종 검증", "릴리스 전 검증" 키워드로 트리거. peach-e2e-setup + peach-e2e-scenario + peach-e2e-suite 3개 스킬의 패턴을 공유하고, 검증 기준은 본 프로젝트 Spec을 필수 기준으로 삼고, ui-proto는 화면/흐름 보조 기준으로 사용한다. peach-team-dev와 함께 하나의 개발-검증 납품 흐름을 이루되, 구현 컨텍스트와 검증 컨텍스트는 분리한다. 팀 실행 방식은 E2E 범위와 런타임 도구 가용성을 분석해 single-agent / role-queue / agent-team 중 선택한다. 단순 코드 동작 검증을 넘어, 기획 의도와 부합하는지 자동 검증하는 게 핵심 차별점.