🇺🇸 English | 🇰🇷 한국어 | 🇯🇵 日本語 | 🇨🇳 简体中文
e2e-skills는 AI 코딩 에이전트가 Playwright와 Cypress E2E 테스트를 생성·검토하고 실패 원인을 분석할 때 쓰는 네 가지 Agent Skills 모음입니다. 새 테스트 생성은 Playwright를 지원하고, 기존 테스트나 PR/diff 범위의 변경 검토와 실패 분석은 Playwright와 Cypress를 지원합니다. 검토 목록 가운데 규칙만으로 판별할 수 있는 항목을 찾는 deterministic scanner도 포함합니다.
e2e-reviewer는 사람이나 AI가 작성한 테스트를 검토하는 독립적인 품질 게이트입니다. 통과한 테스트가 제목에 명시된 동작을 실제로 입증하는지 확인합니다.
| 필요 | 스킬 | 결과 |
|---|---|---|
| 새 Playwright 테스트 생성 | playwright-test-generator |
탐색, 승인, 검토를 거친 Playwright 테스트 |
| Playwright/Cypress 테스트 또는 PR/diff 변경 검토 | e2e-reviewer |
구체적인 수정안과 신규·악화·기존 문제 구분이 포함된, 검증된 P0/P1/P2 문제 목록 |
| 실패한 Playwright 실행 분석 | playwright-debugger |
F1–F15 근본 원인, 근거, 수정안 |
| 실패한 Cypress 실행 분석 | cypress-debugger |
F1–F15 근본 원인, 근거, 수정안 |
deterministic local scan |
skills/e2e-reviewer/scripts/scan.sh |
대상 프로젝트의 패키지 없이 규칙으로 찾은 후보 |
생성기는 테스트가 부족한 영역을 분석하고 실제 브라우저에서 대상 흐름을 탐색합니다. 시나리오가 승인되면 테스트를 생성하고 각 후보를 검증합니다. playwright-debugger와 cypress-debugger는 실패한 실행 산출물을 바탕으로 근본 원인을 분류하고, 판단 근거와 구체적인 수정안을 제시합니다.
false-green 탐지는 테스트 검토 기능의 중요한 부분이지만, 이 프로젝트의 전부는 아닙니다. e2e-reviewer가 찾은 문제를 고친 PR 14건이 Storybook, SvelteKit, code-server, Strapi, Carbon Design System, Ghost, MUI X를 비롯한 업스트림 프로젝트에 병합되었습니다.
code-server에서는 저장소에 들어간
it.only하나 때문에 CI가 7개월 동안 테스트 8개를 조용히 건너뛰었습니다. 건너뛴 테스트 중 하나는 실행하면 실패하는 상태였지만 CI는 계속 통과했습니다.
실행 예제: React optimistic-write 검증에서는 화면 변화만으로 서버 요청과 저장까지 증명할 수 없는 이유를 보여줍니다.
프레임워크별 도우미는 다음처럼 역할이 나뉩니다.
| 필요 | 가장 잘 맞는 선택 |
|---|---|
| 계획에서 Playwright 커버리지를 생성 | Playwright Test Agents |
| 공식 문서를 바탕으로 Cypress 워크플로 작성·설명·활용 | Cypress AI Skills / Cypress AI Toolkit |
| false-green 검토와 실패 보고서 디버깅 | e2e-skills |
e2e-skills는 이러한 공식 툴킷을 보완합니다. 테스트가 이름에 명시된 동작을 실제로 입증하는지, 변경으로 인해 실패해야 할 테스트가 통과하게 됐는지, 실패한 Playwright/Cypress 실행 산출물에서 무엇을 확인할 수 있는지에 초점을 맞춥니다.
Kimi 공식 사이트의 “더 스마트한 QA 자동화를 위한 AI 소프트웨어 테스트 스킬”에 소개되었습니다.
e2e-reviewer가 찾아낸 문제를 고친 PR 14건이 업스트림에 병합되었습니다. 직접 선별한 이 사례들은 실제 활용 사례와 수정 내용을 보여주지만, 전체를 대표하는 검증 표본이나 정확도 추정치는 아닙니다.
| 저장소 | PR | 수정한 패턴 |
|---|---|---|
| Storybook | storybookjs/storybook#34141 | Playwright 검증문의 await 누락 |
| code-server | coder/code-server#7845 | focused test 유출, matcher 없는 expect, 사용하지 않는 가시성 확인 |
| Strapi | strapi/strapi#26630 | 사용하지 않는 탐색 및 상태 확인 |
| SvelteKit | sveltejs/kit#16068 | 기다리지 않는 Playwright 검증문 |
| Carbon Design System | carbon-design-system/carbon#22564 | Locator의 참·거짓 판정을 web-first 검증문으로 교체 |
| Ghost | TryGhost/Ghost#28712 | Promise인 비활성화 상태를 직접 검증 |
| Cal.com | calcom/cal.diy#28486 | E2E 흐름의 약한 검증 패턴 |
| Bruno | usebruno/bruno#8317 | 검증과 대기의 안정성 문제 |
| Qwik | QwikDev/qwik#8777 | Locator/handle 존재 여부만 확인 |
| Element Web | element-hq/element-web#32801 | Locator가 null이 아닌지만 확인 |
| MUI X | mui/mui-x#22982 | UI handle 확인을 상태 검증으로 교체 |
| module-federation/core | module-federation/core#4826 | Cypress 테스트의 불필요하고 포괄적인 uncaught:exception 억제 |
| FiftyOne | voxel51/fiftyone#7851 | Locator 정의 여부 확인을 화면에 나타난 중복 이름 오류 검증으로 교체 |
| Rancher Desktop | rancher-sandbox/rancher-desktop#10557 | not.toBeNull() Locator 검증을 화면에 나타난 WSL 통합 이름 검증으로 교체 |
false-green 테스트는 이름에 적힌 동작이 실제로 작동하는지와 관계없이 통과합니다. 불안정한(flaky) 테스트는 가끔 실패하므로 재시도 대시보드나 flake 분석에서 결국 포착됩니다. 반면 false-green 테스트는 제품에 문제가 있어도 실패하지 않기 때문에, 통과·실패 상태만 감시해서는 드러나지 않습니다.
이 Playwright 테스트는 그럴듯해 보이지만 Locator 객체가 생성됐다는 사실만 증명합니다.
import { expect, test } from '@playwright/test';
test('shows the welcome message', async ({ page }) => {
await page.goto('/dashboard');
expect(page.getByText('Welcome back')).toBeDefined();
expect(page.locator('.user-badge')).not.toBeNull();
});제대로 된 테스트라면 사용자가 보는 동작을 검증하고, 그 동작에 문제가 생기면 실패해야 합니다.
- expect(page.getByText('Welcome back')).toBeDefined()
+ await expect(page.getByText('Welcome back')).toBeVisible()함께 제공되는 스캐너는 별도 설정 없이, 실제 결과를 확인하지 않고도 통과하는 테스트 코드를 찾아냅니다. 아래는 조치에 필요한 줄만 추린 출력입니다.
$ /bin/bash -p skills/e2e-reviewer/scripts/scan.sh tests/
[P0] #4f Locator always-true assertion (truthy/defined/not-null) (2 hits)
.../tests/login.spec.ts:5: expect(page.getByText('Welcome back')).toBeDefined();
.../tests/login.spec.ts:6: expect(page.locator('.user-badge')).not.toBeNull();
Summary: 2 total hit(s), 2 P0이 실행은 P0 문제를 보고하므로 scan.sh는 exit 1로 종료됩니다.
eslint-plugin-playwright도 no-unnecessary-assertions 규칙으로 이 형태를 찾습니다. 커밋 시점의 lint가 잡을 수 있는 문제는 이 규칙에 맡기고, 나머지는 스캐너로 보완하세요.
좋은 matcher만으로는 부족합니다. 동작이 깨지면 테스트가 실제로 실패해야 합니다. V2는 각 후보의 핵심 검증문을 뒤집습니다. V3는 승인된 임시 복사본에 근거가 확인된 제품 결함을 주입하고, 테스트가 미리 지정한 위치에서 예상한 불일치로 실패하는지 확인합니다.
이때 원본은 바이트 단위로 그대로 유지합니다. 제한 시간 초과, 브라우저 충돌, 설정 오류로 인한 실패는 인정하지 않으며, 안전하게 검증할 수 없는 경우에는 CANNOT_VERIFY로 보고합니다.
플러그인 마켓플레이스에서 설치합니다.
/plugin marketplace add voidmatcha/e2e-skills
/plugin install e2e-skills@voidmatcha
또는 검증된 버전으로 고정한 공통 설치 CLI를 사용해 네 스킬을 복사본으로 설치합니다.
npx --yes skills@1.5.21 add voidmatcha/e2e-skills --skill '*' -g -a claude-code네 가지 스킬을 ~/.agents/skills/에 설치합니다.
npx --yes skills@1.5.21 add voidmatcha/e2e-skills --skill '*' -g -a codexCodex에서는 e2e-reviewer, playwright-debugger, cypress-debugger 작업을 전용 에이전트에 맡기거나 현재 세션에서 같은 절차를 직접 수행할 수 있습니다. playwright-test-generator에는 더 엄격한 V6 경계가 적용됩니다. 새 문맥에서 검토할 별도 리뷰어가 없으면 CANNOT_VERIFY와 PARTIAL/BLOCKED를 보고합니다.
여기서 전용 에이전트는 선택적 서브에이전트인 e2e-finding-verifier와 e2e-failure-classifier입니다. Codex는 이 둘을 플러그인으로 설치할 수 없습니다. Codex 플러그인 매니페스트에는 agents 필드가 없고 에이전트 역할은 config 레이어에서만 불러오므로, codex plugin add와 skills CLI 모두 이 둘을 등록하지 않습니다.
지원되는 설치 방법은 두 가지입니다.
bash scripts/dev/install-codex-agents.sh를 실행해 두 에이전트를~/.codex/agents/에 전역 설치합니다.- 이 저장소의 체크아웃에서 작업합니다. Codex 세션이 별도 설치 없이
.codex/agents/를 인식합니다.
두 방법을 모두 건너뛰어도 현재 세션에서 같은 절차를 직접 수행할 수 있습니다. 패키징 경계는 AGENTS.md에서 확인할 수 있습니다.
Codex 플러그인 마켓플레이스를 쓰는 다른 설치 경로:
codex plugin marketplace add voidmatcha/e2e-skills
codex plugin add e2e-skills@voidmatcha
skills CLI가 지원하는 모든 실행 환경에 전역 설치합니다.
npx --yes skills@1.5.21 add voidmatcha/e2e-skills -g --all특정 실행 환경 하나에만 설치하려면 --all을 -a <agent>로 바꿉니다. 지원하는 실행 환경은 supported agents 목록에서 확인할 수 있습니다. 검증되지 않은 새 버전이 실행되지 않도록, 위 명령은 검증된 CLI 릴리스로 버전을 고정합니다.
체크아웃은 ~/.claude/skills/ 밖에 두고, 공개 스킬 디렉터리 네 개를 각각 연결합니다.
git clone https://github.com/voidmatcha/e2e-skills.git "$HOME/.claude/e2e-skills"
mkdir -p "$HOME/.claude/skills"
for skill in playwright-test-generator e2e-reviewer playwright-debugger cypress-debugger; do
ln -s "$HOME/.claude/e2e-skills/skills/$skill" "$HOME/.claude/skills/$skill"
done같은 이름의 스킬이 이미 있으면 링크 생성은 기존 파일을 덮어쓰지 않고 실패합니다. Claude Code에서 /skills를 실행해 네 스킬이 모두 표시되는지 확인합니다.
Review my Playwright tests in tests/e2e with e2e-reviewer.
Generate Playwright E2E coverage for apps/web/e2e.
Debug the failed Playwright report in playwright-report/.
Debug the failed Cypress report in cypress/reports/.
새 E2E 테스트를 만들거나 기존 테스트를 검토하고, 실패한 Playwright/Cypress 실행의 원인을 분석할 때 이 스킬 묶음을 사용하세요. 이 도구는 실제 애플리케이션과 E2E 테스트 모음을 보완하며, 이를 대신하지 않습니다. 범용 lint preset이나 프레임워크에 구애받지 않는 테스트 도구도 아닙니다. Playwright와 Cypress를 지원하되, 새 테스트 생성은 현재 Playwright만 지원합니다.
함께 제공되는 셸 스크립트와 artifact reader는 macOS/Linux 셸을 대상으로 합니다. Windows 사용자는 WSL에서 실행하고 scan/report artifact를 WSL filesystem 안에 두어야 합니다.
새로 만든 테스트가 통과하는 것만으로는 충분하지 않습니다. Locator나 Promise 자체를 검증하거나, 테스트 이름에 적힌 동작과 무관한 상태를 확인하거나, 핵심 검증문이 테스트 결과에 영향을 주지 않을 수도 있습니다. 그래서 생성기는 적용 가능한 V1–V6 검증을 모두 통과하기 전까지 새 테스트를 후보로 취급합니다.
실행 가능한 테스트 코드를 만드는 것과 제품에 문제가 생겼을 때 제대로 실패하는 테스트를 만드는 것은 별개의 일입니다. 이 절차는 규칙으로 찾을 수 있는 문제와 문맥을 읽어 판단해야 하는 문제를 구분합니다.
- 스캐너는 Locator의 참·거짓 판정, focused test, 누락된
await, 모든 오류를 무시하는 처리처럼 규칙만으로 판별할 수 있는 후보를 찾습니다. e2e-reviewer는 문제를 확정하기 전에 테스트 이름, 동작, 검증문, 헬퍼, Page Object, fixture, 설정을 읽습니다.- 확정한 문제에는 안정적인 패턴 ID와 P0/P1/P2 심각도를 붙이므로 수정 전후와 회귀 여부를 비교할 수 있습니다.
- 수정한 뒤에는 스캐너와 프로젝트에서 승인한 E2E 또는
lint명령을 다시 실행합니다.
스캐너가 찾은 결과는 후보일 뿐 최종 판정이 아닙니다. 인증 누락, 네트워크 호출을 입증하지 않는 optimistic UI, 이름과 검증문 불일치, 렌더링 가드를 통과하지 못하는 fixture처럼 여러 파일을 함께 읽어야 판단할 수 있는 문제도 있습니다.
현재 근거로 뒷받침할 수 있는 주장은 제한적입니다. 이 프로젝트에는 동작으로 확인한 개발 근거와 업스트림에 병합된 수정 14건이 있지만, 이를 바탕으로 일반적인 검토 정확도를 주장하지는 않습니다.
- 브라우저 결함 주입은 Playwright/Cypress 셀 36개 중 36개에서 완료했습니다.
- 정밀 리뷰어 벤치마크는 입증된 허위 통과 사례 12개와 정상 코드 보호 사례 12개를 다룹니다. 결함 사례 중 10개에는 바이트 단위로 동일한 연산자 변경을 적용했습니다.
- 독립 견고성 게이트 v4, v5, v7, v8은 사전 등록 기준에 실패했습니다. V6와 v9은 실행하지 않았고, v10은 실행 조건을 확정해 두었지만 아직 실행하지 않았습니다.
debugger프로토콜은 다시 실행할 수 있는 합성 사례 30개를 제공하지만, 독립적으로 확립된debugger정확도를 주장하지는 않습니다.
점수, 실패한 게이트, 대체된 실행, 주장 범위는 벤치마크 현황을 참고하세요. 연구 근거 원장은 인접 분야의 단위 테스트나 맞춤형 에이전트 연구를 이 프로젝트가 직접 측정한 결과처럼 취급하지 않고, 외부 출처 59개를 구분해 검토합니다.
목록에는 ID가 안정적으로 유지되는 Playwright/Cypress test smell 24개가 들어 있습니다. 대표적인 허위 통과 유형으로는 Locator의 참·거짓 판정, 검증문 누락, 오류 무시, focused test, 인증 누락, 네트워크 호출을 입증하지 않는 optimistic UI 검증이 있습니다. 전체 분류와 근거를 참고하세요.
일부 패턴은 테스트뿐 아니라 애플리케이션까지 검토해야 판단할 수 있습니다. #22의 optimistic UI가 대표적인 예입니다. 클릭으로 쓰기 요청이 실제 전송되는지는 spec만 보고 판단할 수 없습니다. 따라서 테스트만 있는 저장소에서는 추측으로 문제를 보고하지 않습니다. 오탐을 줄이기 위한 의도적인 제한이며, 실행 가능한 예제를 컴포넌트와 함께 제공하는 이유이기도 합니다.
기능이 의도대로 동작하지 않아도 테스트가 통과합니다. 실제 검증이 일어나지 않습니다.
| # | 패턴 | 수정 전 | 수정 후 |
|---|---|---|---|
| 1 | 이름과 검증문 불일치 | 이름에는 "status"가 있지만 toBeVisible()만 확인 |
상태 내용을 검증하거나 실제 검증 내용에 맞게 이름 변경 |
| 2 | Then 누락 | 취소한 뒤 텍스트 복원만 확인하고 입력란이 사라졌는지는 확인하지 않음 | 복원된 상태와 입력란이 닫힌 상태를 모두 검증 |
| 3 | 오류 무시 | 테스트의 try/catch, POM의 .catch(() => {}) |
오류가 테스트 실패로 이어지게 하고 POM 메서드에서 실패를 숨기는 catch 제거 |
| 3b | Cypress uncaught:exception 억제 |
cy.on('uncaught:exception', () => false)가 모든 애플리케이션 오류를 무시 |
이미 알려진 특정 오류에만 핸들러를 적용하고 알 수 없는 오류는 다시 throw |
| 4 | 무의미하거나 재시도를 약화하는 검증문 (P0/P1) | P0: 항상 같은 결과를 내는 조건식과 Locator의 참·거짓 판정. P1: 약한 DOM 연결 확인, 한 번만 읽은 값/URL, 제한 시간 0으로 인한 재시도·마감 위험, 사전 입증 없는 요소 부재, 비어 있을 수 있는 컬렉션을 도는 검증문, 약속한 접근성 이름이 빠진 ARIA 스냅샷 | 의미 있는 범위와 자동 재시도를 지원하는 web-first 검증문 사용. 부재를 확인하기 전에 존재를 입증하고, 반복문을 실행하기 전에 컬렉션이 비어 있지 않은지 확인하며, 약속한 접근성 이름을 핵심 검증 조건으로 유지 |
| 5 | 우회 패턴 (5a P0, 5b P1) | if (await el.isVisible()) { expect(...) }, 근거 주석 없는 { force: true } |
조건 없이 항상 검증. 환경 확인은 beforeEach로 이동하고 force: true에는 // JUSTIFIED: 추가 |
| 7 | Focused test 유출 | test.only(...)가 커밋되어 CI가 테스트 하나만 실행하고 나머지는 조용히 건너뜀 |
.only 삭제. 로컬에서 일부만 실행할 때는 --grep 또는 --spec 사용 |
| 8 | 검증문 누락 | 사용하지 않는 locator/boolean이 시나리오의 유일한 검증 | await expect(locator).toBeVisible() 추가. 별도의 검증이나 실패 근거가 이미 있으면 #8 제외 |
| 12 | 인증 설정 누락 | 로그인, storageState, 인증 fixture가 없어 보호된 경로의 테스트가 로그인 화면이나 엉뚱한 화면의 일반적인 요소를 보고도 통과 |
beforeEach 로그인, storageState 설정, 인증 fixture 중 하나 사용. 정상적인 인증 실패를 P0으로 분류하지 않음 |
테스트 자체는 동작하지만 개발자가 결과를 잘못 해석하게 만들거나 CI 시간을 낭비하고, 이후 변경에서 회귀를 놓칠 수 있습니다.
| # | 패턴 | 수정 전 | 수정 후 |
|---|---|---|---|
| 6 | 직접 DOM 쿼리 | evaluate() 안에서 document.querySelector 사용 |
프레임워크의 locator/query API(locator / cy.get) 사용 |
| 9 | 고정 시간 대기 | waitForTimeout(2000) / cy.wait(2000) / waitForLoadState('networkidle') |
프레임워크의 자동 대기를 활용하고 조건 기반 대기 사용 |
| 10 | 불안정한 테스트 패턴 | 근거 주석 없는 items.nth(2), test.describe.serial(), 범위가 정해지지 않은 접근성 이름 부분 문자열(10c), Cypress 비동기 콜백, 변수에 할당한 cy 명령, 계속 이어지는 동작 체인(10d–10f) |
안정적이고 범위가 명확한 locator와 독립적인 테스트 사용. Cypress 작업은 명령 체인 안에 유지하고 Chainable을 값으로 할당하지 않으며 동작 후 다시 쿼리 |
| 13 | 일관되지 않은 POM 사용 | POM을 import했지만 테스트가 POM이 맡은 동작에 직접 page.fill/page.click 사용 |
모든 상호작용을 POM으로 보내 UI 변경 지점을 한곳으로 통합 |
| 14 | 하드코딩된 자격 증명 | 테스트 코드에 loginPage.login('demo-admin', '<literal-password>') 사용 |
process.env.TEST_USER, Playwright 설정의 secret, 테스트 데이터 fixture 사용 |
| 15 | expect()의 await 누락 |
비동기 Locator/Page web-first matcher Promise의 실행 순서와 결과를 확인하지 않음. 거부된 Promise는 대개 나중에 엉뚱한 위치의 오류로 나타남 | matcher Promise를 await하거나 반환. 동기 값 matcher는 제외 |
| 16 | 동작의 await 누락 |
actionability 확인, 동작 순서, 탐색이 뒤따르는 작업과 경합할 수 있음. 거부된 Promise는 대개 나중에 엉뚱한 위치의 오류로 나타남 | 동작 Promise를 await하거나 반환 |
| 17 | 권장하지 않는 Page 셀렉터 API 직접 사용 | 셀렉터 기반 page.click, page.fill과 관련 Page 동작이 Locator 계층을 건너뜀 |
조합성, strictness, 재사용성, 명확한 실패 메시지를 위해 Locator 동작 사용 |
| 18 | expect.soft() 과다 사용 |
필수 조건을 엄격하게 확인하기 전에 핵심 soft assertion을 실행해 전제 조건이 깨진 뒤에도 후속 작업이 계속됨 | 핵심 상태를 먼저 일반 검증문으로 차단하고, soft는 서로 독립적인 세부 항목에만 사용 |
| 19 | 테스트 코드의 모듈 수준 가변 상태 | 테스트 유틸리티 0열의 let seq = 0; 또는 변형되는 const cache = new Map()가 오래 실행되는 worker에 남아 병렬 worker 사이에서 충돌 |
카운터 삭제. Date.now()와 Math.random().toString(36).slice(2, 8)로 고유한 값을 만들거나 상태를 test.beforeEach로 이동 |
| 20 | 모의 처리하지 않은 실제 백엔드 쓰기 | 회원 가입/결제 테스트가 통제된 테스트 경계 없이 공유 또는 영구 상태에 접근 | 쓰기 요청을 stub 처리하거나 일회용 컨테이너, rollback fixture, 격리된 tenant/database처럼 통제된 백엔드임을 입증 |
| 22 | optimistic UI 검증에 호출 근거 없음 |
좋아요 전환 테스트가 aria-pressed 변경만 검증. UI가 먼저 바뀌면 POST가 사라져도 통과 |
UI 검증을 클릭 전에 준비한 page.waitForRequest() 또는 route 적중 flag와 함께 사용 |
약하지만 틀린 것은 아닙니다. 리팩터링할 때 처리합니다.
| # | 패턴 | 수정 전 | 수정 후 |
|---|---|---|---|
| 11 | YAGNI와 좀비 테스트 | 호출되지 않는 clickEdit(), 근거 없이 비어 있는 wrapper class, 다른 테스트와 완전히 중복되는 테스트, 이유나 재검토 기준이 없는 skip |
사용하지 않는 멤버와 좀비 테스트 삭제. 남겨 두는 skip에는 이유와 기한을 명시하고, 의미 없는 간접 계층을 분명히 줄일 수 있을 때만 한 번 쓰는 헬퍼를 인라인화 |
| 21 | 수동으로 캡처한 세션 파일 의존성 | 수동 캡처 스크립트로만 만드는 storageState: 'auth/member.json'이 CI에는 없고 예고 없이 만료 |
API 로그인 헬퍼 또는 setup 프로젝트로 세션을 자동 생성. 수동 파일은 자동 생성 대체 경로가 있는 캐시로만 사용 |
| 23 | 렌더링 가드를 무시하는 fixture | liked 탭의 fixture가 liked: false를 넣어 카드 컴포넌트가 모든 항목에서 return null을 실행. 빈 UI가 인프라 불안정처럼 보임 |
데이터를 넣기 전에 항목 컴포넌트의 조기 반환과 필터를 읽고, 테스트할 화면의 모든 가드를 통과하도록 필드 설정 |
playwright-debugger와 cypress-debugger는 동일한 F1–F15 근본 원인 분류를 사용합니다. Playwright 쪽은 playwright-report/, HTML 보고서, trace.zip, 스크린샷, 범위가 정해진 GitHub Actions 산출물을 입력으로 받습니다. Cypress 쪽은 mochawesome 또는 JUnit 보고서, 스크린샷, 영상, 범위가 정해진 CI 산출물을 받습니다.
| # | 범주 | 주요 신호 |
|---|---|---|
| F1 | 불안정성 / 타이밍 | TimeoutError, 재시도에서 통과 |
| F2 | 깨진 셀렉터 | locator not found, strict mode 위반 |
| F3 | 네트워크 의존성 | net::ERR_*, 예상하지 못한 API 응답 |
| F4 | 검증값 불일치 | Expected X to equal Y, 실제값과 기대값의 순서 반전 |
| F5 | Then 누락 | 동작은 끝났지만 잘못된 상태가 남음 |
| F6 | 조건 분기 누락 | 요소는 조건부로 나타나지만 검증문은 항상 실행 |
| F7 | 테스트 격리 실패 | 단독으로는 통과하지만 테스트 모음에서는 실패 |
| F8 | 환경 불일치 | CI에서만 또는 로컬에서만 발생. viewport, OS, timezone 차이 |
| F9 | 데이터 의존성 | seed data 누락, 하드코딩된 ID |
| F10 | 인증 / 세션 | 세션 만료, 역할별 UI가 렌더링되지 않음 |
| F11 | 비동기/명령 순서 경합 | Playwright의 Promise.all 순서·병렬 실행 경합, Cypress의 요청 이후 intercept 등록·명령 체인 순서 뒤바뀜·visit/request 경합 |
| F12 | POM / Locator 불일치 | DOM 구조가 바뀌었지만 POM은 갱신되지 않음 |
| F13 | 오류 무시 | .catch(() => {})가 실제 실패를 숨김 |
| F14 | 애니메이션 경합 | 콘텐츠가 아직 렌더링되지 않았거나 일시적인 요소가 관찰 전에 사라짐 |
| F15 | Hydration 경합 | 동작은 성공하지만 효과가 없음. SSR 페이지의 hydration이 끝나기 전에 다음 검증문이 실행되어 실패 |
여기서는 F11과 F12에 프레임워크 공통 이름을 사용합니다. 각 debugger는 같은 고정 코드에 해당하는 프레임워크별 이름을 보고합니다.
두 debugger 스킬은 제품 회귀와 깨지기 쉬운 테스트를 구분해 분류하고, 근거와 구체적인 수정안을 제시합니다. 실패한 Playwright 또는 Cypress 테스트 산출물이 없으면 애플리케이션이나 백엔드를 진단하지 않습니다.
규칙만으로 판별할 수 있는 검사 계층을 직접 실행합니다.
/bin/bash -p skills/e2e-reviewer/scripts/scan.sh path/to/tests스캐너에는 PCRE2를 지원하는 rg와 Python 3가 필요합니다. Python은 NUL-safe 후보 식별 레코드를 생성하고 검증합니다. 따라서 후보 드리프트나 손상된 레코드는 fail-closed로 처리됩니다. 이 필수 기록 작업은 선택적인 Tier 2 AST 도구와 별개입니다.
기본적으로 대상 프로젝트가 제어하는 ESLint 실행 파일, 플러그인, 파서, 설정을 실행하지 않으며 도구도 내려받지 않습니다. 신뢰하는 체크아웃에서 프로젝트 ESLint를 실행하려면 E2E_SMELL_ALLOW_PROJECT_ESLINT=1을 설정합니다. 고정 버전 도구 다운로드는 E2E_SMELL_NO_ESLINT_DOWNLOAD=0과 E2E_SMELL_NO_AST_GREP_DOWNLOAD=0으로 각각 명시적으로 허용합니다.
이식성을 확인할 때 미리 설치된 호스트 실행 파일을 무시하려면 E2E_SMELL_DISABLE_AST_GREP=1을 설정합니다.
읽기 범위.
번들 검사는 요청한 path 아래의 소스를 보고합니다. 프레임워크 출처 확인은 포함 프로젝트의 다른 위치에 있는 relative fixture/support import도 읽을 수 있습니다.
번들 검사는 .ts, .js, .tsx, .jsx, .mts, .mjs, .cts, .cjs 소스를 읽습니다.
Tier 3는 기본으로 제공되는 대체 경로입니다. 선택적으로 사용하는 ESLint와 ast-grep 계층은 정밀도를 높이지만 테스트 의도와 주변 코드를 확인하는 검토를 대신하지 않습니다. 인프라 또는 파일시스템 오류가 발생하면 스캐너는 문제가 없다고 잘못 보고하지 않고 종료 코드 2로 끝납니다. 신뢰와 네트워크 경계는 SECURITY.md를 참고하세요.
eslint-plugin-playwright와 eslint-plugin-cypress는 커밋마다 적용하기 좋은 구문 규칙 기준선입니다. e2e-skills는 여기에 두 가지 계층을 더합니다.
- 사용자가 명시적으로 허용하지 않는 한 대상 프로젝트의
lint도구를 실행하지 않는 안전한 기본 설정의 스캐너 - 테스트 의도나 여러 파일의 관계를 확인해야 하는 문제를 위한 의미 검토
lint 도구는 Locator의 참·거짓만 확인하는 검증문이나 누락된 await를 찾을 수 있습니다. 하지만 "shows a duplicate-name error"라는 테스트가 실제로 오류를 확인하는지, 보호된 경로의 테스트가 인증을 빠뜨렸는지, optimistic UI 검증문이 백엔드 요청까지 증명하는지는 판단할 수 없습니다. 지속적인 lint에는 플러그인을, 테스트 신뢰도 점검에는 e2e-reviewer를 사용하세요.
e2e-reviewer는 목록에 있는 패턴 24개를 모두 검토합니다. 각 패턴에는 고정 ID와 P0/P1/P2 심각도가 지정돼 있습니다. 독립 실행 scan.sh 스캐너는 규칙만으로 판별할 수 있는 일부 항목만 다룹니다. 스캐너 결과는 검토 후보일 뿐 확정된 문제가 아닙니다. 이 스킬은 판정을 내리기 전에 테스트 의도와 주변 코드를 확인합니다.
두 debugger 스킬은 고정된 F1–F15 분류 체계에 따라 실패를 분류합니다. 이 스킬들과 생성기는 저장소를 신뢰하고 환경 변수와 플래그를 포함한 정확한 명령을 승인한 뒤에만 대상 프로젝트가 제어하는 코드를 실행합니다.
비공개 벤치마크 실행에서는 --isolation-wrapper가 필수 훅이지만, 그 자체로 실제 격리를 보장하지는 않습니다. 지속적 통합(CI)은 래퍼 계약을 검증하지만 파일시스템, 프로세스, 네트워크 격리를 입증하지는 않습니다.
검토할 테스트 디렉터리를 e2e-reviewer에 지정하세요. 규칙으로 찾은 후보와 테스트 의도, 주변 코드를 함께 확인해 검토 결과를 제시합니다.
아니요. 변경할 때마다 애플리케이션과 실제 E2E 테스트 모음을 실행하세요. 이 스킬 묶음은 테스트 품질을 검토하고, Playwright 테스트를 작성하며, 기존 실패를 진단합니다. 테스트 실행기는 아닙니다.
병합하기 전에 생성된 테스트를 e2e-reviewer로 검토하세요. 각 테스트가 이름에 명시된 사용자 동작을 실제로 입증하는지 확인하고 false-green 위험을 찾아냅니다. 또한 규칙만으로 찾을 수 있는 후보와 테스트 의도·주변 코드를 함께 살펴야 판단할 수 있는 문제를 구분해 보고합니다.
검토와 실패 분석은 두 프레임워크를 모두 지원합니다. 새 테스트 생성은 현재 Playwright만 지원합니다. cypress-debugger는 mochawesome과 JUnit 보고서를 받습니다.
예. 로컬 보고서 산출물이나 지원되는 GitHub Actions 실행 정보를 제공하면 됩니다. debugger는 F1–F15 분류를 사용해 환경, 타이밍, 셀렉터, 데이터, 인증, 제품 회귀 원인을 구분합니다.
Claude Code와 Codex, 그리고 skills CLI가 지원하는 55개 이상의 실행 환경에서 공개 SKILL.md 계약을 불러올 수 있습니다. 실행 환경별 에이전트 파일을 선택적으로 설치하면 지원되는 환경에서 작업 분담이 나아지지만, 공개 스킬은 해당 파일 없이도 사용할 수 있습니다.
- AI가 생성한 Playwright와 Cypress E2E 테스트를 검토하는 방법
- Playwright와 Cypress E2E
test smell24개 - 규칙 자체 감사
- 오픈소스 사례 연구
- 벤치마크 현황과 실패 결과
- 외부 연구 근거 원장
- 과거 AI 리뷰어 벤치마크
debugger벤치마크 프로토콜- 지원 프레임워크 범위
- 로드맵
앞으로 모델 간 규칙 적용의 일관성을 높이고 규칙 기반 검사의 범위를 넓힐 계획입니다. 전용 검증을 통과하기 전에는 로드맵의 어떤 항목도 출시된 기능으로 설명하지 않습니다.
버그 제보, 오탐 방지 사례, 새로운 안티패턴, 번역 기여를 환영합니다. 설정 방법과 검증 요구사항은 CONTRIBUTING.md를 참고하세요. 에이전트가 따라야 할 유지보수 규칙은 AGENTS.md에 있습니다.
Apache-2.0 © voidmatcha. LICENSE를 참고하세요.
