본문으로 건너뛰기
5분 AI.
TRENDSHIFT MONTHLY #20 딥다이브 · 2026-10-23 분석

e2e 딥다이브
— AI가 조작하고, 테스트가 증명하는 앱 검증

테스트 프레임워크

빠른 판단

무엇
AI의 자연어 화면 조작과 코드 어서션·확인된 동작 재생을 결합한 TypeScript E2E 프레임워크
이럴 때
웹·모바일의 사용자 흐름을 유연한 화면 조작으로 실행하면서 결과는 명시적 조건으로 검증할 때
입력
자연어 행동 목표와 코드로 정의한 결과 검증 조건
결과
실행·검증 결과와 반복 실행에 재사용할 동작 기록
자연어로 앱을 움직이는 에이전트와 코드로 결과를 확인하는 테스트를 한 실행기에 담았습니다. 검증된 동작을 재생하는 캐시, 웹·모바일을 잇는 엔진 계약, 실패를 다루는 워커 구조를 따라가며 믿을 수 있는 자동화를 만드는 법을 배웁니다. TypeScript 계열 약 20.7만 줄 중 패키지 테스트가 약 9.6만 줄입니다. 저장소: tester-army/e2e · ⭐11,746 · 포크 610 · Apache-2.0 (2026-10-23 GitHub 기준) · 코드·규모는 커밋 7e72ea2 기준.
목차
  1. 프로젝트 한줄 요약
  2. 왜 주목받는가
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 분석
  5. 디렉토리 구조 해부
  6. 학습 포인트 (기술별)
  7. 하드웨어 / 시스템 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크

1프로젝트 한줄 요약

자연어로 행동을 맡기고, 관측 가능한 결과로 합격을 결정한다

e2e는 웹과 모바일 앱의 사용자 흐름을 검사하는 TypeScript 테스트 프레임워크입니다. agent.act()로 목표를 주면 에이전트가 화면을 읽고 조작합니다. 같은 테스트 안에서 expect(screen.getByRole(...))로 결과를 확인할 수 있습니다.

행동을 유연하게 만드는 일과, 행동의 결과가 맞는지 증명하는 일을 분리한 것이 이 프로젝트의 핵심입니다. AI에게 모든 판정을 맡기지 않아도 되고, 반대로 모든 클릭을 사람이 미리 지정할 필요도 없습니다.

용어 풀이
E2E 테스트 · assertion · locator
E2E는 사용자가 보는 입구부터 결과까지 이어서 검사하는 방식입니다. assertion은 “상태 문구에 완료가 있어야 한다” 같은 합격 조건이고, locator는 그 문구나 버튼을 찾는 주소록입니다. 함수 하나의 계산만 확인하는 단위 테스트와 검사 범위가 다릅니다.

1-1. 짧은 테스트로 읽는 역할 분담

아래는 가입 폼을 가진 학습용 앱을 가정한 예시입니다. docs/examples/quickstart/tests/agent.e2e.ts의 API 형태를 바탕으로, 목표와 확인 문구를 한국어로 바꿨습니다. 앱에 맞는 역할·이름·완료 문구가 있어야 합니다.

import { test } from '@e2e-dev/web';
import { expect } from 'e2e';

test('방문자가 체험 계정을 만든다', async ({ app, agent, screen }) => {
  await app.open('/');
  await agent.act('이름 {name}, 이메일 {email}로 무료 체험을 신청해 줘', {
    params: { name: '김배움', email: 'learner@example.test' },
  });
  await expect(screen.getByRole('status')).toContainText('체험 시작');
});

app은 앱의 입구, agent는 목표를 수행하는 조작자, screen은 플랫폼 공통 화면 탐색 창구입니다. 웹 엔진의 test를 가져오면 웹 전용 browser fixture도 사용할 수 있습니다. 공통 API만 쓰는 테스트는 e2e의 test로도 작성합니다.

한 문장 비유

AI는 길을 찾는 운전기사, assertion은 도착지를 확인하는 검표원입니다

“도서관까지 가 주세요”라고 하면 기사는 상황에 맞춰 길을 고릅니다. 하지만 기사가 “도착했다”고 말한 것만으로 목적지가 맞다고 확정하지 않습니다. 건물의 간판과 주소를 다시 확인해야 합니다.

e2e의 재생 캐시는 확인된 운행 경로를 저장합니다. 다음에는 그 경로를 따라가되, 현재 길과 도착 상태가 맞지 않으면 일반 모드에서 다시 기사에게 판단을 맡깁니다.

1-2. AI 없이도 출발할 수 있다

README는 “에이전트 단계가 없는 테스트에는 모델이 필요 없다”고 설명합니다. packages/e2e/package.json에서도 ai와 모델 제공자 패키지를 선택적 peer dependency로 선언합니다. 먼저 locator 기반 테스트를 익히고, 변화가 잦은 조작 부분에만 에이전트를 추가하는 학습 순서가 가능합니다.

이 글에서 배울 것
AI 테스트 도구를 넘어, 확장 가능한 실행기를 읽는 연습

엔진 계약, 지연된 캐시 확정, 프로세스 격리, 시간 예산, 입력 검증을 함께 읽습니다. 이 개념들은 테스트 도구뿐 아니라 작업 큐, 플러그인 시스템, AI 자동화 서비스에도 그대로 연결됩니다.

2왜 주목받는가

트렌드의 사실과, 설계에서 읽히는 관심 요인을 구분한다

2-1. 짧은 기간에 모인 관심

2026-10-23 GitHub 기준 스타 11,746, 포크 610이며, 2026-07-22 생성되어 약 3개월 만에 TrendShift Monthly #20에 선정됐습니다. 이 숫자는 관심의 규모를 보여 줍니다. 실제 사용자 수, 성공률, 유지보수 비용까지 설명하는 수치는 아닙니다.

공개된 순위만으로 인기가 오른 원인을 확정할 수는 없습니다. 다만 README의 사용 방식과 소스 구조를 보면, 선택자 유지보수 부담을 줄이려는 시도, 반복 실행의 모델 비용을 줄이는 재생, 웹·모바일 공통 작성 방식이 개발자의 관심을 끌 만한 요소입니다. 다음 비교는 이 설계에 근거한 해석입니다.

2-2. 기존 자동화와 무엇이 다른가

비교 축기존 방식의 출발점e2e의 선택과 대가
Playwright Test웹의 page·locator로 동작을 명시Playwright 위의 별도 실행기. 자연어 목표를 섞지만 설정·API를 다시 배워야 함
Maestro모바일 흐름을 YAML 명령으로 기술TypeScript와 공통 screen API 사용. 모델을 쓸 때는 호출 비용·판정 변동을 관리해야 함
매번 모델로 조작실행할 때마다 화면을 해석하고 행동 결정검증된 act 동작은 재생 가능. 화면 변화나 동적 작업에서는 모델에 다시 넘길 수 있음
플랫폼별 테스트웹·모바일 도구를 따로 구성공통 runner와 assertion을 공유. 각 플랫폼의 지원 기능까지 같아지는 것은 아님

비교 근거는 저장소의 docs/migrate/playwright.mdx, docs/migrate/maestro.mdx, packages/web/src/engine.ts입니다. 다른 제품의 전체 기능이나 성능 우열을 평가한 표는 아닙니다.

e2e는 Playwright를 버리는 도구가 아니라, Playwright 기반 웹 엔진과 별도 모바일 엔진을 하나의 테스트 실행 방식으로 묶는 도구입니다.

2-3. “모델 호출 0회”는 어느 범위의 이야기인가

README의 재생 설명은 조건을 충족한 에이전트 행동 단계에 해당합니다. packages/e2e/src/cache/identity.ts의 TraceCacheKind는 'act'만 허용합니다. agent.assert(), agent.waitFor(), agent.extract()는 현재 화면을 모델로 판단하므로 재생하지 않습니다.

상황소스에서 확인되는 동작
검증된 act 재생 성공그 act의 모델 호출을 건너뛸 수 있음
그 뒤 agent.assert 실행판정용 모델 호출은 별도로 발생
일반 모드에서 재생 불일치현재 상태에서 executor로 넘겨 이어서 수행
strict 모드에서 낡은 기록REPLAY_STALE로 실패. 기록 없는 새 단계는 여전히 실시간 실행 가능
새 모델 성능 비교모델 변경만으로 캐시가 비워지지 않으므로 --no-cache 필요
비유

재생 캐시는 시험의 정답지를 복사하는 장치가 아니라, 답을 구하는 작업 순서를 다시 사용하는 장치입니다. 현재 결과의 검사는 계속 필요합니다. 판정까지 과거 기록으로 대신하면 틀린 결과를 영원히 통과시킬 수 있기 때문입니다.

2-4. 관심보다 더 유용한 학습 근거

packages/*/src의 TypeScript 계열 구현은 85,397줄, packages/*/tests는 95,892줄입니다. 테스트에는 단위·통합·타입 검사가 포함됩니다. 테스트 줄 수가 많다고 정확성이 증명되는 것은 아니지만, 성공 경로 외에 실패·중단·낡은 캐시를 어떻게 명세하는지 읽을 재료가 풍부합니다.

한편 Playwright 마이그레이션 문서는 fullyParallel의 동등 기능과 HTML 리포터가 없다고 표시합니다. 실제 packages/e2e/src/report/builtin.ts의 기본 리포터도 list, json, junit, markdown 네 가지입니다. 익숙한 도구의 기능을 전부 대체한다고 생각하면 학습과 도입 범위를 잘못 잡게 됩니다.

3기술 스택 전체 지도

버전은 각 의존성 파일의 선언값이며, 제품 전체의 단일 버전이 아니다

3-1. 백엔드에 해당하는 부분: Node.js 실행기

이 저장소의 중심은 상시 운영하는 API 서버나 데이터베이스가 아니라 로컬 또는 CI에서 실행되는 Node.js 프로세스입니다. CLI가 설정과 테스트를 읽고, 워커가 앱·브라우저·기기를 다룹니다. MCP 서버도 이 실행 자원을 연결하는 창구이며, 일반 웹 서비스의 백엔드와 역할이 다릅니다.

부품실제 선언역할 · 근거 파일
언어·실행 환경TypeScript 7.0.2
Node ^22.22.3 || >=24.8.0
ESM 기반 SDK·CLI. packages/e2e/package.json
CLIcommander 15.0.0
@clack/prompts 1.8.1
명령·옵션 파싱과 초기 설정 질문. 같은 파일
설정·코드 해석oxc-parser 0.154.0
oxc-transform 0.154.0
테스트·설정 코드를 다루는 도구. 같은 파일
형식·단언zod 4.6.1
@vitest/expect 5.0.5
값의 구조와 assertion 기반. 같은 파일
모델 연결ai ^7.0.0 선택적 peer
개발용 고정값 7.0.107
AI SDK를 이용한 모델·도구 호출. 같은 파일
MCP@modelcontextprotocol/server 2.3.1외부 코딩 에이전트가 도구를 호출하는 서버. 같은 파일
이미지 비교fast-png 8.0.0
pixelmatch 8.0.0
스크린샷 처리·픽셀 차이 비교. 같은 파일

e2e 패키지는 0.21.2, 웹 엔진은 0.15.2, 모바일 엔진은 0.12.3입니다. 최신 GitHub 릴리스 표기인 @e2e-dev/testmu@0.0.1을 runner의 버전으로 읽으면 안 됩니다.

의존성 읽기
dependency · peer dependency · dev dependency
dependency는 패키지가 직접 필요로 하는 부품입니다. peer는 사용자의 프로젝트가 호환 버전으로 함께 준비할 부품이고, dev는 저장소 개발·검증용입니다. 모델 SDK가 선택적 peer라는 것은 locator 테스트에 모델 패키지를 강제하지 않는다는 설계와 연결됩니다.

3-2. 자동화 엔진과 프론트엔드를 분리해서 보기

영역실제 버전무엇을 위한 코드인가
웹 엔진playwright-core 1.64.1packages/web/package.json. 브라우저 제어용이며 React UI 라이브러리가 아님
모바일 엔진agent-device 0.21.29packages/mobile/package.json. 기기 조작·접근성 화면 읽기
웹 벤치마크next 16.4.1
react 19.3.1
apps/web-benchmark/package.json. 어려운 UI를 테스트하는 대상 앱
모바일 벤치마크expo 57.0.22
react-native 0.86.2
react 19.2.3
apps/mobile-benchmark/package.json. 네이티브 화면·권한 창 등의 테스트 대상
문서 사이트mint 4.2.909docs/package.json. Mintlify 문서 개발·검증 도구

따라서 “Next.js와 Expo가 e2e를 구동한다”는 해석은 틀립니다. 이들은 테스트받는 앱의 스택입니다. 프레임워크 자체를 쓸 때 대상 앱이 React나 Expo일 필요는 없습니다. examples/에는 SwiftUI·Compose·Flutter·.NET MAUI 예제도 있습니다.

3-3. 인프라·빌드·품질 검사

항목선언·설정배울 점
모노레포pnpm@12.3.4루트 package.json. workspace는 packages/*, apps/*, docs
정적 검사oxlint 1.83.0
fallow 3.27.0
문법·오류 가능성과 사용하지 않는 코드 검사. 루트 package.json
테스트·릴리스vitest 5.0.1
@changesets/cli 3.0.3
패키지 테스트와 여러 npm 패키지의 변경·배포 관리
컴파일target: ES2023
module: NodeNext
tsconfig.base.json. 엄격한 타입 검사와 ESM 경로 처리
CI 호환성Node 22, 24, 26, 22.22.3, 24.8.0.github/workflows/spec.yml. 최신 계열과 지원 최저점을 함께 검사
실행 환경Linux 4 vCPU · macOS 6 vCPUBlacksmith runner 라벨 기준. 개발자 PC의 최소 요구량은 아님

pnpm-workspace.yaml에는 allowBuilds로 의존성 빌드 허용 여부를 적고, undici 등의 하위 버전을 overrides로 조정합니다. ignoreWorkspaceCycles: true도 있습니다. 웹 엔진은 runner를 peer로 쓰고 runner 개발 테스트는 웹 엔진을 사용하므로, 루트 빌드는 패키지 순서를 명시합니다.

의존성의 이름을 외우기보다, 실행 제품·테스트 대상·개발 도구 중 어디에 쓰이는지 구분하는 것이 기술 스택을 읽는 첫 단계입니다.

4아키텍처 심화 분석

한 번의 테스트가 설정에서 실행·검증·기록까지 이동하는 길

4-1. 전체 시스템 구조도

사용자가 작성한 e2e.config.ts + tests/*.e2e.ts
                      |
                      v
          e2e CLI / runner 공개 API
                      |
          설정 해석 · 수집 · 대상 선택
                      |
          buildWorkPlans / runUnits
                      |
          +-----------+------------+
          |                        |
     워커 프로세스 A           워커 프로세스 B
     한 target에 연결          한 target에 연결
          |                        |
          +---- 테스트 attempt ----+
                      |
       app / screen / expect / agent
                      |
        +-------------+----------------+
        |                              |
   locator assertion               agent.act
        |                              |
        |                   StepTraceSession.begin
        |                     /              \
        |                 재생 가능          기록 없음·일반 모드 불일치
        |                    |                    |
        |                replayTrace        StepExecutor
        |                    |              기본: AI SDK 도구 루프
        +--------------------+--------------------+
                             |
                 e2e/engine 공통 계약
                  /                    \
    @e2e-dev/web                        @e2e-dev/mobile
    PlaywrightSurface                  AgentDeviceSurface
         |                                  |
    브라우저 / BrowserProvider          기기 / DeviceProvider

  뒤따른 검증 성공 --> 쓰기 허용 시 attempt 종료 때 캐시 확정
  결과·실패 근거   --> JSON / JUnit / Markdown / 터미널
  외부 코딩 에이전트 --> MCP stdio --> 세션·동작 도구

위 도식의 중심은 화면 자체가 아니라 화면을 관찰하고 조작하는 공통 계약입니다. 모델과 재생기, locator가 서로 다른 브라우저를 직접 만지는 대신 같은 실행 계층을 통과합니다. 이 덕분에 예산·정책·기록 규칙을 여러 구현에 반복해서 쓰는 부담을 줄입니다.

4-2. 패턴 ① 계약과 capability로 구현을 교체한다

packages/e2e/src/engine/manifest.ts의 defineEngine()은 이름·버전·spiVersion을 확인하고, 제공된 훅으로 capability 집합을 만듭니다. 일반 객체의 알 수 없는 키는 오류입니다. perform이 있으면 observe와 지원 actions도 있어야 합니다.

// defineEngine()의 실제 검증 중 일부
if (spec.perform !== undefined) {
  if (!capabilities.has('observation')) {
    throw invalid(name, 'declares perform without observe: action targets are observation refs');
  }
  if (spec.actions === undefined) {
    throw invalid(name, 'declares perform without actions: list the action kinds the surface honors');
  }
  capabilities.add('actions');
}

즉 “버튼을 누를 수 있다”는 선언은 “지금 관찰한 버튼을 가리킬 수 있다”는 조건에 기대고 있습니다. TypeScript 타입만으로는 JavaScript 설정이나 외부 패키지의 실제 값을 보장하지 못하므로, 설정을 불러올 때 실제 값도 검증합니다.

구현 파일·함수공통 계약에 맞추는 작업
packages/web/src/engine.ts
web()
PlaywrightSurface를 만들고 observe·locate·perform에 연결. browser fixture 기여
packages/mobile/src/engine.ts
buildEngine()
AgentDeviceSurface를 같은 계약에 연결. 기기 풀 크기를 workers 제한에 반영하고 device fixture 기여
packages/mobile/src/nodes.ts
projectSnapshot()
기기의 평평한 접근성 목록을 트리로 복원하고 플랫폼 역할을 공통 역할로 투영
packages/web/src/provider.ts
BrowserProviderScope
worker 단위로 빌릴지 attempt마다 새 브라우저를 빌릴지 수명 선택
설계 용어
Adapter · 의존성 역전 · capability
Adapter는 서로 다른 기계를 같은 모양의 콘센트에 연결하는 변환기입니다. 실행기는 e2e/engine이라는 계약을 알고 엔진이 여기에 맞춥니다. capability는 “이 엔진이 실제로 제공하는 기능 목록”입니다. 같은 콘센트에 연결된 기계라고 모든 기능까지 같다고 가정하지 않습니다.

4-3. 패턴 ② 기록과 신뢰 확정을 두 단계로 나눈다

packages/e2e/src/agent/step-cache.ts의 StepTraceSession은 캐시 조회·재생·실시간 기록을 맡습니다. stage()는 시작·종료 화면의 차이와 경로를 담은 기록을 준비합니다. 화면·경로 변화가 없거나 안전하게 기록할 수 없으면 저장 후보를 만들지 않습니다.

실시간 act 수행
    |
    +-- TraceRecorder가 확정된 동작 기록
    |
    +-- stage(): 종료 경로·등장/사라진 화면 단서 수집
    |
    +-- 뒤의 검증 단계 통과 여부 기록
    |
    v
settleStagedTraces(): attempt 종료 시, read-write·strict 해제 기준
    |
    +-- 뒤에서 검증됨 --> saved / kept
    +-- 검증 안 됨   --> unconfirmed / 조건에 따라 기존 항목 삭제
    +-- 중단됨       --> 저장·삭제하지 않음

핵심 비교식은 packages/e2e/src/cache/context.ts의 settleStagedTraces()에 있습니다. 현재 기록보다 뒤에 있는 검증 단계가 통과해야 승인됩니다. 테스트가 오류 없이 끝났다는 사실만으로는 충분하지 않습니다.

// 실제 승인 조건. 단계 번호는 시간 순서다.
const confirmed = entry.stepIndex < settlement.lastVerifiedStepIndex;

// 개념 예: act(2) → locator assertion(3)이 통과했다.
// 2 < 3 이므로 act 기록은 확인된 후보가 된다.

packages/e2e/src/cache/identity.ts는 프로젝트·테스트·대상·엔진 이름과 SPI·명령·매개변수·에이전트 문맥 등을 키에 담습니다. 같은 명령을 반복해도 호출 순번으로 구분합니다. 모델 변경과 엔진 패키지 버전 변경은 직접적인 키 변경 사유가 아닙니다. 엔진 이름과 SPI는 키에 들어가며, 실제 화면 적합성은 재생 중 다시 확인합니다.

packages/e2e/src/agent/step-cache.ts의 StepTraceSession은 replayTrace()로 새 관측에서 대상을 다시 찾고, endStateMatches()에서 목표 상태가 재생 전부터 있었는지와 최종 상태가 맞는지를 확인합니다. 일반 모드에서 중간 재생이 어긋나면 진행한 앞부분을 전달하고 현재 화면에서 executor가 이어받습니다.

비유

식당에서 주문서를 적는 일과 손님에게 음식이 맞게 나갔다고 확인하는 일은 다릅니다. 기록은 주문서이고, 뒤따른 검증은 배식 확인입니다. 이 코드는 주문서를 썼다는 이유만으로 다음 주문의 모범 답안으로 채택하지 않습니다.

캐시의 가치는 저장 속도보다, 무엇을 다시 믿어도 되는지 결정하는 승인 규칙에 있습니다. 이 구조는 데이터베이스의 완전한 트랜잭션은 아니지만, 실행 중 준비와 종료 시 확정을 분리하는 사고법을 보여 줍니다.

저장 계층도 학습할 만합니다. packages/e2e/src/cache/store.ts의 FileCacheStore는 항목을 1,048,576바이트로 제한하고 SHA-256 형태의 키만 파일명으로 씁니다. packages/e2e/src/internal/atomic-write.ts의 writeFileAtomic()은 옆 임시 파일에 쓴 뒤 이름을 바꿉니다. 동시 기록은 잠금 없이 마지막 쓰기가 남는 구조이며, 캐시는 복구 가능한 보조 데이터로 취급합니다.

캐시의 기본 모드는 로컬에서 read-write, CI에서는 read-only입니다. 다만 설정으로 명시한 read-write는 CI에서도 유지하며, 사용자 정의 store는 CI의 기본 읽기 전용 전환에서 제외됩니다. strict 모드에서는 설정한 쓰기 모드와 관계없이 항목을 쓰거나 삭제하지 않습니다. packages/e2e/src/config/resolve.ts의 기본값 처리에서, 기본 쓰기 정책과 명시적인 설정을 구분하는 방식을 볼 수 있습니다.

4-4. 패턴 ③ 스케줄러를 상태와 수명으로 설계한다

packages/e2e/src/run/units.ts의 buildWorkPlans()는 setup 작업과 일반 파일 작업을 나눕니다. packages/e2e/src/run/scheduler.ts의 runUnits()가 이를 배분하며, 워커 하나는 한 target에 묶여 한 번에 한 작업 단위를 실행합니다. 같은 파일의 테스트는 선언 순서를 유지하고 파일 사이에서 병렬 실행합니다.

워커 상태: starting --> idle --> busy --> idle
                                  |
                        실패·인프라 문제 등
                                  v
                               retired --> 프로세스 종료

  target별 setup 완료 --> 그 target의 일반 파일 배정
  전체 workers 제한 + 엔진의 workers 제한 + 남은 작업 수

packages/e2e/src/run/worker/handle.ts의 ChildProcessRunner는 fork()와 IPC로 워커를 만들고 통신합니다. 종료 판정에는 exit보다 IPC가 비워진 뒤의 close 이벤트를 사용합니다. 워커가 사라지기 직전에 보낸 결과를 놓치지 않으려는 선택입니다.

plannedSlots()는 실행기 제한·엔진 제한·작업 수의 최솟값을 계산합니다. longestFirst()는 이전 실행에서 오래 걸린 파일을 먼저 배정하고 실행 시간 기록이 없는 파일은 그보다 우선 실행합니다. 워커를 늘리는 것 외에 마지막에 긴 파일 하나가 남는 시간을 줄이는 방법도 있음을 보여 줍니다.

재시도는 packages/e2e/src/run/retry.ts의 isRetryEligible(), runWithRetries(), retryVerdict()가 공유합니다. 시간 초과나 test 범주 오류가 대상이며, 다시 성공한 결과는 단순 passed가 아니라 flaky입니다. 오류가 설정 문제인지, 테스트 실패인지에 따라 대응이 달라집니다.

4-5. 패턴 ④ 모델의 제안을 닫힌 도구와 정책으로 제한한다

packages/e2e/src/agent/tool-loop.ts의 createToolLoopExecutor()는 도구 실행 루프·종료 판정·반복 감지·호출 수 집계를 묶습니다. 모델의 텍스트를 셸이나 임의 코드로 평가하는 방식이 아니라, 허용된 도구 인자를 해석해 실행 계층에 전달합니다.

packages/e2e/src/agent/secrets.ts의 authorizeSecretFill()은 등록된 비밀인지, 대상이 활성화된 편집 필드인지, password 용도의 비밀이 password 필드로 가는지 확인한 다음에야 값을 꺼냅니다. packages/e2e/src/cache/recorder.ts의 TraceRecorder는 typeSecret의 평문 대신 비밀 이름을 기록합니다.

다만 정책을 만능 격리로 읽으면 안 됩니다. packages/e2e/src/internal/urls.ts의 resolveNavigationUrl()은 http:·https:·정확한 about:blank를 허용하지만 호스트 허용 목록은 없습니다. 비밀 입력 승인에도 출처 제한이 없습니다. 테스트·설정·엔진 코드는 실행한 사용자의 OS 권한으로 작동합니다.

설계에서 가져갈 원칙
모델의 판단과 실행 권한은 다른 층에 둔다

모델이 어떤 도구를 쓰자고 제안해도, 실제 허용 여부는 실행기가 결정합니다. 이 구조를 따라 만들 때는 허용 도구뿐 아니라 네트워크 목적지·기기 권한·테스트 코드의 신뢰 범위까지 별도로 설계해야 합니다.

5디렉토리 구조 해부

공개 패키지, 이를 사용하는 앱, 문서와 예제를 갈라 읽는다
e2e/
├── package.json / pnpm-workspace.yaml / pnpm-lock.yaml
├── tsconfig.base.json
├── packages/
│   ├── e2e/
│   │   ├── src/
│   │   │   ├── cli/ · config/ · collect/
│   │   │   ├── run/worker/
│   │   │   ├── engine/ · locator/ · expect/
│   │   │   ├── agent/ · cache/
│   │   │   └── report/ · mcp/ · oauth/ · telemetry/
│   │   ├── schema/
│   │   └── tests/  (unit/ · integration/ · types/ · live/)
│   ├── web/ · mobile/
│   ├── kernel/ · lightpanda/ · smol/
│   ├── eas/ · limrun/ · testmu/
│   └── decision/ · github/
├── apps/
│   ├── testbed/
│   ├── web-benchmark/
│   └── mobile-benchmark/
├── docs/  (reference/ · migrate/ · integrations/ · examples/)
├── examples/  (with-vite/ · with-next/ · with-expo/ 등)
├── scripts/
├── skills/ · plugins/
└── .github/workflows/
디렉토리역할과 읽는 목적
packages/e2e/srcSDK·runner·CLI 본체. 호출을 입력 검증에서 결과 기록까지 추적
packages/web
packages/mobile
공통 계약을 실제 브라우저·기기에 연결. 플랫폼 차이를 흡수하는 위치
서비스 연동 패키지Kernel·TestMu·EAS 등의 공급자를 연결. 핵심 실행기가 공급자 SDK를 직접 알 필요를 줄임
packages/decision선택 확률 기반 모델용 executor. 도구 루프 구현을 바꿀 수 있는 확장 지점
packages/e2e/schema리포트·세션·에이전트 판정의 JSON wire 형식. 저장·전달되는 데이터 계약
apps/testbed빌드된 패키지를 실제 사용자처럼 소비하는 검증 앱. runner 동작 재현에 적합
두 benchmark 앱iframe·canvas·네이티브 알림 등 어려운 화면의 회귀 검사. 일반 사용법 예제와 구분
examples기술별 독립 사용자 프로젝트. pnpm workspace에는 포함되지 않음
docs · skills사람과 코딩 에이전트가 읽는 사용 지침. 문서 예제의 타입 검사도 수행
scripts · .github배포·버전·문서 정합성·설치 검증과 CI 자동화

처음부터 모든 디렉토리를 읽기보다 docs/examples/quickstart/ → packages/web/src/engine.ts → packages/e2e/src/engine/manifest.ts → packages/e2e/src/agent/step-cache.ts 순서로 내려가면 사용법에서 계약과 구현으로 자연스럽게 연결됩니다.

처음 보는 모노레포에서는 “배포되는 코드”와 “그 코드를 사용하는 검증 앱”부터 가르면 읽어야 할 범위가 크게 줄어듭니다.

6학습 포인트 (기술별)

파일을 읽고 끝내지 말고, 작은 모형으로 원리를 옮겨 본다

6-1. TypeScript: 타입과 실제 값의 경계

tsconfig.base.json은 strict 외에도 두 가지 중요한 옵션을 켭니다. exactOptionalPropertyTypes는 “키가 없음”과 “키는 있고 값이 undefined임”을 구분합니다. noUncheckedIndexedAccess는 배열·사전 조회 결과가 없을 수 있음을 드러냅니다.

// 학습용 축약 예시
type Options = { timeout?: number };
const absent: Options = {};
const present: Options = { timeout: 5000 };
// const wrong: Options = { timeout: undefined }; // 엄격 옵션에서는 오류

const table: Record<string, number> = { web: 1 };
const slots = table['mobile'];
if (slots !== undefined) console.log(slots + 1);

작은 실습: 선택적 설정 키를 세 개 만들고, 누락·undefined·잘못된 문자열을 각각 넣어 보세요. 타입 오류와 defineEngine() 같은 실행 중 오류가 서로 다른 입력 경로를 지킨다는 점을 설명해 봅니다.

6-2. 기술별 읽기와 확장 실험

기술실제 파일·식별자배울 것과 작은 실습
접근성 모델packages/mobile/src/nodes.ts
ROLE_MAP, projectSnapshot()
text-field를 textbox로 통일하는 변환. 가짜 iOS·Android 입력 세 개를 공통 역할로 매핑
선언형 APIpackages/e2e/src/locator/expression.ts
packages/e2e/src/locator/engine.ts
요소를 찾는 요청을 데이터로 표현. 버튼 이름을 담은 객체를 두 종류의 가짜 화면에 적용
비동기 취소packages/e2e/src/expect/poll.ts
pollMatcher()
개별 assertion과 attempt 마감의 최솟값 사용. 느린 읽기를 중단했을 때 다음 단계가 오염되지 않는지 설계
프로세스 통신packages/e2e/src/run/worker/handle.ts
ChildProcessRunner
메시지와 수명 관리. 요청·시작·결과·종료 네 메시지의 순서를 종이에 그리기
캐시 식별 기준packages/e2e/src/cache/identity.ts
normalizeInstruction()
줄바꿈·유니코드 정규화와 문맥 키. 공백·명령·매개변수를 바꾸며 어떤 항목이 달라져야 할지 예측
파일 일관성packages/e2e/src/internal/atomic-write.ts
writeFileAtomic()
임시 파일과 rename. 쓰기 도중 중단되어도 기존 파일 또는 새 파일 중 하나가 남아야 하는 이유 설명
스키마 검사packages/e2e/tests/unit/schema-fixtures.test.ts
packages/e2e/schema/
올바른 예와 틀린 예를 같이 유지. 필수 필드 하나를 빠뜨린 리포트가 왜 거절돼야 하는지 정리
MCP 입출력packages/e2e/src/mcp/server.ts
serveMcp()
표준 출력은 프로토콜, 진단은 별도 경로. 로그 한 줄이 JSON 통신에 섞이면 생기는 문제 재현 구상

코드 흐름을 읽을 때는 함수 하나의 구현과 그 함수를 검증하는 테스트 한 개를 짝지으면 이해 부담이 줄어듭니다.

6-3. 폴링은 “계속 기다리기”보다 좁은 개념이다

packages/e2e/src/expect/poll.ts의 pollMatcher()는 읽기 함수를 다시 호출하고 조건을 검사합니다. 개별 마감과 attempt 마감 중 빠른 쪽에서 멈추며, 취소 신호도 함께 받습니다. 읽기 자체가 끝나지 않는 경우에도 시간 제한을 적용합니다.

비동기 용어
deadline · timeout · AbortSignal
timeout이 “5초 동안”이라면 deadline은 “몇 시 몇 초까지”입니다. 여러 작업이 하나의 deadline을 공유하면 앞 단계에서 시간을 쓴 만큼 다음 단계의 시간이 줄어듭니다. AbortSignal은 시간이 남았어도 취소됐음을 전달하는 신호입니다.

주의할 세부사항도 있습니다. docs/cache.mdx는 expect.poll()과 일반 값 assertion을 캐시 승인용 검증으로 세지 않는다고 설명합니다. 화면 locator assertion은 packages/e2e/src/expect/async.ts에서 verifies: true로 기록됩니다. “assertion이라는 이름이면 모두 같은 부수 효과가 있다”는 가정을 버리는 좋은 사례입니다.

같은 성공·실패를 표현하는 API라도, 실행 기록에서 맡는 역할은 다를 수 있으므로 호출부와 기록부를 함께 읽어야 합니다.

6-4. 테스트에서 요구사항을 복원하는 법

  1. packages/e2e/tests/unit/retry.test.ts에서 재시도 뒤 성공을 무엇이라 부르는지 찾습니다.
  2. packages/e2e/tests/unit/step-cache.test.ts에서 저장되는 경우와 저장되지 않는 경우를 나눕니다.
  3. packages/e2e/tests/integration/trace-cache-replay.test.ts에서 실제 화면과 재생을 연결하는 검사를 읽습니다.
  4. packages/e2e/tests/types/sdk-types.ts에서 @ts-expect-error로 금지하는 API 조합을 봅니다.

이 네 파일은 각각 상태 정책, 캐시 정책, 통합 동작, 공개 타입 계약을 보여 줍니다. 하나의 큰 테스트로 전부 확인하려 하기보다 실패 원인을 어느 층에서 빨리 발견할 수 있는지가 좋은 테스트 분할의 기준입니다.

7하드웨어 / 시스템 요구사항

공식 설정에서 확인되는 조건과 학습용 자원 가늠치를 구분한다

7-1. 먼저 확인할 소프트웨어 조건

사용 범위필요한 환경근거·주의점
SDK·CLINode ^22.22.3 || >=24.8.0각 핵심 패키지의 engines.node. 단순히 “Node 22 이상”이라고 줄이면 범위가 달라짐
저장소 개발pnpm 12.3.4루트 packageManager. 일반 사용 프로젝트의 패키지 관리자와 구분
로컬 웹 테스트브라우저 바이너리와 OS 의존 라이브러리playwright-core 패키지와 브라우저 실행 파일은 별개. CI도 Chromium 설치 단계를 둠
로컬 iOSmacOS·Xcode·시뮬레이터·대상 앱.github/workflows/mobile.yml은 macOS에서 xcrun simctl 등으로 환경 확인
로컬 AndroidAndroid SDK·에뮬레이터·가상화 환경CI는 KVM, API 36, x86_64, google_apis, pixel_7 사용
에이전트 단계지원 모델 연결과 필요한 인증·네트워크API·구독·로컬 모델 등의 선택지는 README 기준. 기본 모델은 자동으로 정해지지 않음
원격 기기·브라우저해당 서비스 계정·토큰·접속 환경로컬 기기 부담을 옮길 수 있으나 공급자 비용과 지원 기능을 따로 확인

Node 범위의 ^22.22.3은 22 계열의 해당 패치 이상을 뜻하며, 뒤의 >=24.8.0과 합쳐집니다. 범위에 들어간다는 것과 CI에서 모든 버전을 시험했다는 것은 다릅니다. CI에서 명시적으로 검사하는 조합은 3절 표의 다섯 항목입니다.

7-2. 메모리·CPU·GPU는 얼마나 필요할까

핵심 설정 파일과 CI에는 PC용 공식 최소 RAM·디스크 용량이 명시되어 있지 않습니다. 아래 값은 단일 워커로 배우기 위한 보수적인 계획치이며, 프로젝트가 보증하는 최소 사양이나 실측 결과가 아닙니다.

학습 시나리오시작 계획치자원이 늘어나는 이유
소스 읽기·웹 1개현대적 4코어급 CPU·RAM 8GB부터 검토편집기·앱 서버·브라우저를 함께 띄움. 큰 앱이면 여유 메모리 추가
모바일 1개RAM 16GB 이상을 우선 검토IDE·빌드 도구·시뮬레이터가 동시에 메모리를 사용
웹·모바일 병렬RAM 32GB급 또는 원격 자원 검토워커마다 브라우저·기기와 앱 자원이 늘어남. 먼저 1개로 안정성 확인
GPU원격 모델 사용 시 별도 학습용 GPU 불필요로컬 모델을 선택하면 그 모델의 메모리·GPU 요구량이 추가됨
디스크브라우저·SDK·앱 빌드·영상 보관 공간 확보고정 GB 수보다 보관 정책과 설치할 플랫폼 수가 중요

packages/e2e/vitest.config.ts는 실제 브라우저·앱·워커 프로세스를 쓰는 통합 테스트를 maxWorkers: 3으로 제한합니다. CPU가 밀리면 올바른 기능도 시간 초과처럼 보일 수 있기 때문입니다. 내 학습 환경에서는 workers: 1부터 시작하는 편이 원인을 구분하기 쉽습니다.

7-3. 시간 제한도 시스템 자원이다

설정기본값의미
timeout / launchTimeout120,000 / 60,000ms테스트 한 시도와 엔진 초기화·시도 준비에 쓰는 서로 다른 예산
actionTimeout / assertionTimeout30,000 / 5,000ms동작과 조건 확인을 같은 길이로 기다리지 않음
cleanupTimeout30,000ms각 afterEach 훅·fixture 해제·엔진 정리에 주는 시간 예산
retries로컬 0 · CI 1기본 재시도 횟수. 명시 설정·CLI가 우선
workers로컬 가용 병렬도의 절반 내림, 최소 1 · CI 1엔진·작업 수에 의해 실제 배정이 더 줄 수 있음

근거는 packages/e2e/src/config/resolve.ts입니다. 느린 환경에서 모든 timeout을 크게 늘리기 전에 어떤 단계가 밀리는지 확인해야 합니다. 앱 준비 실패, assertion 불일치, 모델 응답 지연은 서로 다른 문제입니다.

8직접 해볼 수 있는 실습 과제

완료 조건과 관찰할 근거가 있는 다섯 과제

아래 과제는 본인 소유의 학습용 앱과 별도 테스트 프로젝트를 전제로 합니다. 예시의 http://localhost:3000은 앱의 실제 주소에 맞추고, 외부 서비스에 가입·결제하는 시나리오는 로컬 모형으로 대체합니다. 코드는 커밋 7e72ea2의 API 형태를 기준으로 합니다.

과제 1 · 입문

모델 없이 “버튼을 누르면 완료 문구가 나온다” 확인하기

준비: 이름 입력란, 제출 버튼, role="status" 결과 영역을 가진 작은 웹 앱을 준비합니다. 테스트용 의존성은 e2e@0.21.2와 @e2e-dev/web@0.15.2 조합을 기준으로 맞춥니다.

구현: 아래 설정에서 시작하고, locator로 입력과 제출을 수행합니다. 모델 설정 없이 실행되는지 확인합니다.

// e2e.config.ts
import type { E2EConfig } from 'e2e';
import { web } from '@e2e-dev/web';

export default {
  targets: [{ name: 'web', engine: web(), app: { url: 'http://localhost:3000' } }],
  workers: 1,
} satisfies E2EConfig;
// tests/greeting.e2e.ts
import { test } from '@e2e-dev/web';
import { expect } from 'e2e';

test('이름을 제출하면 인사한다', async ({ app, screen }) => {
  await app.open('/');
  await screen.getByRole('textbox', { name: '이름' }).fill('김배움');
  await screen.getByRole('button', { name: '제출' }).click();
  await expect(screen.getByRole('status')).toContainText('김배움');
});
# 의존성과 Chromium이 준비된 학습 프로젝트에서
npx e2e run tests/greeting.e2e.ts --workers 1 --reporter list,json

완료 기준: 올바른 결과에서는 통과하고, 앱이 다른 이름을 표시하도록 바꾸면 실패해야 합니다. 버튼 이름을 바꿨을 때와 결과 문구를 바꿨을 때의 오류를 비교해 보세요.

과제 2 · 중급

같은 사용자 흐름을 AI 조작과 캐시로 수행하기

준비: 공식 quickstart를 따라 모델과 인증을 설정합니다. 과제 1의 입력·클릭 부분을 agent.act()로 바꾸되 마지막 locator assertion은 남깁니다. 캐시는 read-write 모드로 설정합니다.

실험: 첫 실행과 두 번째 실행의 step.cache.mode, step.cache.write, 모델 호출 수를 비교합니다. 그 뒤 locator assertion을 지우고 캐시를 비운 상태에서 다시 기록합니다. 저장이 승인되지 않는 이유를 4절의 비교식으로 설명합니다.

// 모델·캐시 설정을 마친 테스트 본문의 일부
await agent.act('이름 {name}을 입력하고 제출해 줘', {
  params: { name: '김배움' },
});
await expect(screen.getByRole('status')).toContainText('김배움');

완료 기준: “모델이 성공이라고 말함”, “뒤의 확인이 통과함”, “기록이 저장됨”을 세 칸으로 나눈 관찰표를 만듭니다. 이어서 agent.assert()도 추가해 재생된 act와 실시간 판정의 호출을 구분합니다.

과제 3 · 중급

샤딩 계산과 SDK 입력 검증을 손으로 재현하기

읽을 곳: packages/e2e/src/collect/select.ts의 shardItems()·applyShard(), packages/e2e/src/run/runner.ts의 validateRunOptions()입니다.

실험: 단일 target·agent 조합에서 일반 테스트 다섯 개와 serial 그룹 하나를 세 shard로 나눈다고 가정합니다. serial 그룹을 하나의 항목으로 센 뒤, 각 shard의 구간을 계산합니다. 그룹 안 테스트 수가 많으면 실행 시간까지 균등해지는지도 생각해 보세요.

// applyShard()의 실제 구간 계산
const size = Math.floor(items.length / shard.total);
const remainder = items.length % shard.total;
const from = (shard.index - 1) * size + Math.min(shard.index - 1, remainder);
const to = from + size + (shard.index - 1 < remainder ? 1 : 0);

완료 기준: 항목 여섯 개라면 세 구간이 각각 두 항목이고, 한 그룹이 갈라지지 않음을 표시합니다. index: 0, index: 4, total: 3, 소수·NaN 입력을 왜 거절해야 하는지 적습니다. 최신 커밋의 주제가 바로 SDK의 숫자 shard 검증입니다.

과제 4 · 고급

가짜 화면으로 엔진 계약의 실패 조건 설계하기

구현: 독립 실험 프로젝트에서 defineEngine()을 이용해 버튼 하나의 observe 결과를 돌려주는 모형을 설계합니다. 처음에는 관찰만 제공하고, 다음에는 perform과 actions를 함께 추가합니다. 구체적인 노드 형식은 packages/e2e/src/engine/contract.ts와 공식 엔진 작성 문서를 따릅니다.

실패 사례: observe 없는 perform, 오타 키, 지원하지 않는 SPI 버전, 예약 fixture 이름을 각각 넣었을 때 어느 단계에서 거절돼야 하는지 표로 만듭니다.

완료 기준: 브라우저 코드 없이도 계약 검증의 의미를 설명하고, 잘못된 선언이 테스트 실행 전 INVALID_CONFIG로 막혀야 함을 확인합니다. 구현을 바꾸는 것과 계약을 바꾸는 것의 차이도 적습니다.

과제 5 · 고급

재시도 정책을 작은 상태 기계로 옮기기

읽을 곳: packages/e2e/src/run/retry.ts와 packages/e2e/tests/unit/retry.test.ts. 실제 앱 없이 가짜 attempt 결과의 배열만 사용해 같은 판정 규칙을 구현합니다.

입력 사례: 첫 시도 성공, test 오류 후 성공, 시간 초과 후 성공, 설정 오류, 첫 실패 뒤 재시도 도중 취소, 자체 skip을 비교합니다. 종료 상태와 시도 횟수를 함께 기록합니다.

완료 기준: 재시도로 성공한 결과가 flaky이고, 설정·인프라 오류를 무조건 반복하면 안 되는 이유를 설명합니다. 이후 scheduler가 실패한 워커를 교체하는 문제와 테스트를 재시도하는 문제를 별개로 그려 보세요.

실습의 완료 기준은 초록색 통과 표시 하나가 아니라, 의도적으로 틀리게 만들었을 때 예상한 층에서 실패하는지까지 확인하는 것입니다.

9관련 기술 심화 학습 로드맵

6주 동안 사용법 → 계약 → 실행기 → 신뢰 규칙으로 내려가기

주당 3~5시간을 가정한 학습 계획입니다. TypeScript·Promise가 처음이면 1주차를 늘리고, 모바일 환경 준비가 어렵다면 웹과 가짜 화면만으로 5주차까지 진행할 수 있습니다.

주차읽을 개념·소스손에 남길 결과물
1주차TypeScript의 객체·union·async/await. tsconfig.base.json, quickstart 예제모델 없는 테스트 한 개와 “어떤 조건에서 실패하는가” 설명
2주차접근성·role·locator·대기. packages/e2e/src/locator/expression.ts, packages/e2e/src/expect/async.ts, packages/e2e/src/expect/poll.ts고정 sleep을 조건 대기로 바꾼 예제와 시간 제한 표
3주차Adapter·capability·수명. packages/e2e/src/engine/manifest.ts, 두 엔진의 engine.ts웹·모바일 훅 대응표와 최소 가짜 엔진 설계
4주차캐시 키·후조건·지연 확정. packages/e2e/src/cache/identity.ts, packages/e2e/src/agent/step-cache.ts, packages/e2e/src/cache/context.ts첫 기록·재생·불일치·검증 없음의 네 실행 흐름도
5주차프로세스·IPC·재시도·샤딩. packages/e2e/src/run/units.ts, packages/e2e/src/run/scheduler.ts, packages/e2e/src/run/retry.ts워커 상태 그림과 shard 구간 계산표
6주차도구 정책·MCP·CI 계약. packages/e2e/src/agent/secrets.ts, packages/e2e/src/mcp/server.ts, .github/workflows/spec.yml입력→권한 확인→실행→증거의 경계 지도와 작은 설계 발표 자료

주마다 소스 한 곳과 테스트 한 곳만 골라도 됩니다. 중요한 것은 읽는 파일 수보다 입력·출력·실패 조건을 본인 말로 다시 설명하는가입니다.

9-1. 관심 분야에 따른 다음 갈림길

학습 속도 조절
설명할 수 없는 부분만 다시 읽는다

“왜 assert를 재생하지 않는가?”, “왜 워커 종료를 close로 기다리는가?”, “왜 설정도 실행 중 검증하는가?”를 자료 없이 설명해 보세요. 막히는 질문이 다음에 읽을 소스를 정해 줍니다.

좋은 딥다이브의 끝은 저장소의 모든 파일을 아는 상태가 아니라, 작은 설계 선택의 이유를 다른 문제에 적용할 수 있는 상태입니다.

10핵심 키워드 사전

처음 만나는 용어를 이 저장소의 실제 쓰임과 연결하기
용어쉬운 설명
E2E사용자가 앱에 들어와 조작하고 결과를 얻는 흐름을 이어서 검사하는 테스트
assertion실행 결과가 반드시 만족해야 하는 합격 조건
locator역할·이름·텍스트 등으로 현재 화면의 요소를 찾는 요청
fixture테스트 실행에 준비해 전달하는 도구·자원. 여기서는 app·screen·browser·device 등
target엔진과 앱 정보를 묶은 테스트 실행 대상. 웹·iOS·Android 등을 별도로 선언
attempt테스트를 한 번 시도한 실행. 재시도가 생기면 attempt도 추가됨
worker테스트 작업을 받아 실행하는 일꾼. 기본 실행 경로는 별도 자식 프로세스
shard전체 선택 항목 중 일부를 다른 기계·CI 작업에 나누어 맡기는 조각
serial group순서와 상태 의존성을 지키며 실행하는 그룹. 샤딩 때 target·agent 조합별로 한 항목으로 취급
flaky처음에는 실패했지만 재시도에서 통과한 결과. 안정적인 통과와 구분하는 신호
engine · SPI실제 화면을 다루는 구현과, 그 구현이 runner에 맞춰야 하는 연결 계약
capability엔진이 실제 지원한다고 선언한 기능. 지원하지 않는 기능을 미리 구분하는 목록
semantic tree화면을 픽셀 대신 역할·이름·값·상태·부모 자식 관계로 표현한 구조
observation · revision현재 화면을 읽은 결과와 그 관측을 구분하는 표식. 오래된 요소 참조를 구분하는 데 사용
StepExecutor목표를 받아 실행 단계를 수행하는 교체 가능한 구현. 기본 AI 루프나 다른 실행기를 연결
tool calling모델이 허용된 함수 이름과 구조화된 인자를 제안하면 프로그램이 검증 후 수행하는 방식
replay · hand-off과거 동작을 현재 화면에서 재현하는 것과, 맞지 않는 지점에서 실시간 실행기로 넘기는 것
postcondition동작이 끝난 뒤 보여야 하는 상태. 이 캐시는 종료 경로와 화면 변화 단서를 함께 확인
cache key어느 문맥에서 만든 기록인지 구분하는 식별자. 명령만 같다고 기록을 공유하지 않게 함
unique()실행마다 달라지는 입력을 재생 시 현재 값으로 바꿀 수 있게 표시하는 API
strict cache존재하던 기록이 낡았으면 실시간 보정으로 숨기지 않고 실패시키는 실행 모드
atomic write임시 파일을 완성한 뒤 교체하여 반쯤 쓴 결과가 정식 파일로 보이지 않게 하는 쓰기 방식
redaction모델 입력·기록 등에 민감한 문자열이 드러나지 않도록 가리거나 치환하는 처리
deadline · cancellation언제까지 실행할지 정하는 마감과, 그 전에라도 멈추라는 신호
MCP · stdioAI 도구 연결 규약과 표준 입출력을 통한 통신. 프로토콜 출력과 일반 로그를 섞지 않아야 함
monorepo · workspace여러 패키지를 한 저장소에 두고 의존성·빌드·검사를 함께 관리하는 구성
golden snapshot기대하는 변환 결과를 파일로 고정하고, 코드 변경 후 차이를 검토하는 테스트 기준
telemetry명령·엔진·오류 분류 같은 사용 정보를 수집하는 기능. 비활성화 설정 제공

용어를 다시 읽을 때는 “그 용어가 어떤 실패를 막는가”를 붙여 보세요. revision은 낡은 관측, timeout은 끝나지 않는 대기, postcondition은 동작만 했을 뿐 결과는 틀린 재생, 스키마는 잘못된 데이터 형식을 다루는 장치입니다.

11참고 링크

변하는 문서는 공식 사이트에서, 분석 근거 코드는 고정 커밋에서 읽는다

11-1. 공식 저장소·사용 문서

11-2. 이 글의 주요 코드 근거

11-3. 관련 기술의 공식 학습 자료

현재 상태 (2026-10-23 확인)

항목확인 내용
프로젝트·설명tester-army/e2e · 웹·모바일 앱을 위한 차세대 E2E 테스트 프레임워크
트렌드TrendShift Monthly #20 선정
스타 / 포크11,746 / 610 · 2026-10-23 GitHub 기준
주 언어 / 생성일TypeScript / 2026-07-22
최근 push2026-10-22
최신 릴리스@e2e-dev/testmu@0.0.1 · 2026-10-16 · GitHub 릴리스 기준
핵심 패키지 버전e2e 0.21.2 · @e2e-dev/web 0.15.2 · @e2e-dev/mobile 0.12.3 · 커밋의 package.json 기준
최근 커밋7e72ea2 · 2026-10-22 · SDK list의 숫자 shard 검증 수정 (#996)
전체 추적 파일2,025개 · 커밋에 포함된 파일 목록 기준
TypeScript 계열.ts 193,378줄 / 1,069개 · .tsx 13,370줄 / 78개 · 합계 206,748줄
패키지 구현 / 테스트packages/*/src 85,397줄 / 396개 · packages/*/tests 95,892줄 / 452개 · .ts·.tsx 기준
JavaScript 계열.js·.jsx·.mjs·.cjs 합계 4,603줄 / 21개
기타 코드Swift 407줄 · Kotlin·Kotlin 설정 756줄 · Dart 261줄 · C# 105줄 · CSS 1,605줄
문서 규모.md·.mdx 합계 39,455줄 / 192개
라이선스 / 개발 단계Apache-2.0 / README는 1.0 이전의 활발한 개발 단계로 설명

줄 수는 커밋 7e72ea2의 Git 추적 파일을 확장자별로 세었으며 빈 줄·주석·테스트·예제를 포함합니다. 마지막 개행이 없는 줄도 한 줄로 셉니다. JSON·잠금 파일·이미지·바이너리는 위 코드 합계에서 제외했습니다. 테스트 비중은 코드 커버리지를 뜻하지 않습니다.

쓰기 전에 알아둘 한계
도입과 학습에서 놓치지 말아야 할 다섯 가지

① API가 아직 바뀔 수 있습니다. README는 1.0 이전이며 minor 릴리스 사이에도 API·설정이 바뀔 수 있다고 밝힙니다. 본문의 버전과 현재 문서의 버전을 맞추고, 패키지별 peer 범위를 확인해야 합니다.

② 재생이 모든 판단과 비용을 없애지는 않습니다. act만 캐시 대상이며 에이전트 판정은 실시간입니다. 플랫폼·화면 변화·동적 값·기록 불가 작업에서는 재생이 멈추거나 기록되지 않을 수 있습니다. 이 글의 구조 설명은 특정 성공률이나 실행 속도를 보증하지 않습니다.

③ 지원 범위가 기존 도구와 같지 않습니다. 기본 HTML 리포터는 없고, 플랫폼별 engine capability도 다릅니다. 브라우저 엔진의 지원 기능을 모바일에도 그대로 가정하거나 Playwright 설정을 그대로 옮길 수 없습니다.

④ 정책은 OS 샌드박스가 아닙니다. 테스트·설정·엔진은 사용자 권한으로 실행됩니다. 탐색과 비밀 입력에는 호스트 허용 목록이 없으며, 일반 텍스트·화면 정보는 선택한 모델 제공자에게 전달될 수 있습니다. 신뢰할 수 없는 코드는 외부 격리 환경에서 다뤄야 합니다.

⑤ 환경과 기록 보관을 따로 관리해야 합니다. 기기·브라우저 설치, 모델 인증·요금, 영상·추적 파일 보관은 운영 조건에 포함됩니다. CLI의 사용 정보 수집은 E2E_TELEMETRY_DISABLED=1 또는 npx e2e telemetry disable로 끌 수 있습니다. 이를 꺼도 모델 호출 자체가 로컬 처리로 바뀌지는 않습니다.