반응형

전체 글 285

[TIL][Claude Code] 게이트는 깨봐야 게이트다 — Playwright 규율 훅이 조용히 죽는 세 가지 방식

# PreToolUse(Edit|Write) 훅 — 스텝 파일에 raw 로케이터가 들어오면 exit 2 로 차단 if grep -qE '\bpage\.locator\(' &2 exit 2 fi 이 훅이 오늘도 막고 있을 거라 믿으면, 함정에 걸린 거다훅은 세운 날 동작한다, 그리고 그 뒤로 아무도 다시 확인하지 않는다훅으로 Playwright 규율을 강제하고 있었다Claude Code 로 E2E 시나리오를 짜게 하면서 규율을 CLAUDE.md 에 적어 두는 것으로는 부족했다로케이터는 Page Object 에만 두고 스텝은 POM 메서드만 호출한다,이유 없는 test.skip 은 금지다, 커밋 제목은 영어다 —이런 규칙은 에이전트가 급해지면 가장 먼저 무너진다그래서 규칙을 훅으로 옮겼다PreToolUs..

TIL/Playwright 2026.09.05

[TIL][Playwright] 비동기 작업의 완료를 동기적으로 기다리지 않기

채팅으로 입력을 받아 장시간 걸리는 예측 작업을 실행하는 LLM 에이전트 서비스를 검증하고 있다 "이 입력으로 예측해줘" 하면 에이전트가 백그라운드 작업을 시작한다 처음 작성한 happy-path 검증은 아래와 같다 1. 입력을 붙여넣고 전송2. 결과 카드가 뜰 때까지 기다린다 (최대 20분)3. 카드가 뜨면 통과결과는 항상 타임아웃이었다20분을 꽉 채우고 실패처음엔 작업이 느린 줄 알고 타임아웃을 늘렸다그래도 실패했고, 그 시점에 백엔드를 의심하기 시작했다하지만 원인은 백엔드가 아니었다원인제품 동작을 오해하고 있었다, 이 예측은 비동기 백그라운드 작업이다에이전트의 실제 흐름은 이렇다승인 → 작업 시작 → "작업 ID 발급했고, 완료되면 알려줄게" → 턴 종료전송한 그 턴 안에서 결과가 인라인으로 오지 ..

TIL/Playwright 2026.07.14

[TIL][Playwright] AI 챗봇 응답 감지 #2 — follow-up 함정과 nth 인덱스

#1에서 Copy 버튼 등장을 응답 완료 신호로 정리했다첫 질문에는 잘 동작했다follow-up 질문에서 함정이 드러났다함정 재현Scenario: AI 챗봇에 두 번 질문한다 Given AI Assistant 페이지에 진입한다 When "Aspirin 의 구조를 알려줘" 메시지를 전송한다 Then AI 응답이 표시된다 # ✅ 통과 When "부작용도 알려줘" 메시지를 전송한다 # follow-up Then AI 응답이 표시된다 # ⚠️ 즉시 통과 — 새 응답 도착 전두 번째 Then 이 응답 스트리밍 시작도 전에 통과한다# 기대: "Aspirin 은 소염진통제..." # 실제 (검증 시점): "" (응답 비어있음) # ..

TIL/Playwright 2026.06.21

[TIL][Playwright] AI 챗봇 응답 완료를 E2E 로 감지하는 방법

자동화 커버리지를 넓히다가 이제 AI Assistant 의 차례가 됐다 일반적인 UI 검증과 달리 AI 챗봇은 응답이 언제 끝나는지 알 수 없다 일반 UI: 버튼 선택 → 모달 열림 (100ms) AI 챗봇: 메시지 전송 → 응답 스트리밍 → 완료 (2초~30초)wait_for_timeout(5000) 으로 때우면 빠른 응답은 시간 낭비가 되고, 느린 응답은 타임아웃이다 문제: 응답 완료 시점을 어떻게 아는가 AI 챗봇의 응답은 스트리밍으로 한 글자씩 나온다 응답 중간에 텍스트를 읽으면 불완전한 내용이 캡처된다 시도한 접근법들1. wait_for_timeout(10000) → 빠른 응답도 10초 대기, 느린 응답은 실패2. 텍스트 길이 변화 감시 (polling) → 스트리밍 중 잠깐 멈추는 구간..

TIL/Playwright 2026.06.14

[TIL][Playwright] expect vs wait_for — disabled 버튼 때문에 30초 날린 이야기

E2E 검증에서 파일 업로드 후 "다음" 버튼 선택하는 코드가 있었다 30초 타임아웃 걸리면서 터졌다 원인을 찾아보니 버튼이 disabled 상태인데 클릭을 시도한 거였다 상황: 뭐가 터졌나 파일 업로드 모달에서 SDF 파일을 선택하고 "다음" 버튼을 선택하는 Step 이었다 Error: playwright._impl_.errors.TimeoutError: Locator.click: Timeout 30000ms exceeded. - waiting for get_by_role("button", name="다음").last - locator resolved to - 56 × waiting for element to be visible, enabled and stable - retrying click..

TIL/Playwright 2026.06.07

[TIL] Claude Code 커스텀 스킬로 반복 작업 자동화하기

매번 비슷한 요청을 타이핑하고 있었다 "테스트 실패 원인 분석해줘 allure-results 확인하고 에러 메시지 파싱해서 로케이터 문제인지 확인하고"복붙하기도 귀찮고 매번 미묘하게 다르게 써서 결과도 들쭉날쭉 💡 해결: 커스텀 스킬 Claude Code 의 슬래시 명령어(/commit, /review 등)를 직접 만들 수 있다 .claude/commands/ 폴더에 마크다운 파일 추가하면 끝 📁 디렉토리 구조 .claude/└── commands/ ├── coverage_check.md ├── create_e2e_test.md ├── find_e2e_test.md ├── health_check.md ├── init_plan_mode.md ├── lint.md ├..

TIL/Claude Code 2026.05.31

[TIL][Pytest] All Pass 알림은 거짓말이었다

E2E Automation 슬랙 채널에 ✅ All Pass 알림이 왔다 리포트를 열어보니 Total Test Case 개수가 평소와 달랐다 실행되지 않은 케이스가 있었다 원인: Allure 결과 디렉터리 카운트 기반 집계 결과 집계 스크립트는 Allure 결과 파일 개수로 passed/failed를 덮어쓰는 구조였다 # 의도된 동작passed = count_allure_results(status="passed")failed = count_allure_results(status="failed")total = passed + failedpytest watchdog이 hang된 pytest를 SIGTERM으로 죽이는 순간, 진행 중·미실행 케이스는 Allure 결과 파일을 남기지 않는다집계에서 빠진다passe..

TIL/Claude Code 2026.05.24

[TIL][Claude] GitHub Actions 에서 Playwright E2E 매일 자동 실행하기

E2E Suite 가 200개를 넘었다 make parallel # 7-Phase 병렬 실행나름 안정화가 돼서 CI 를 붙여봤다 CI 구조 매일 오전 6시에 돌고, Slack 으로 결과를 받는다 매일 06:00 KST (cron) ↓GitHub Actions: Playwright headless ↓7-Phase 병렬 실행 ↓Allure Report 생성 → gh-pages 배포 ↓Slack 알림 (카테고리별 PASS/FAIL)수동 실행도 가능하다 — Phase 5 에서 터졌으면 5 부터만 재실행 가능 on: workflow_dispatch: inputs: from_phase: description: '시작 Phase (1-7)' d..

TIL/Playwright 2026.05.17

[TIL][Playwright] networkidle이 React 앱에서 거짓말하는 이유 — MutationObserver로 DOM 안정화 대기 내장

wait_for_network_idle()을 호출했는데 그 직후 요소를 찾지 못해 실패한다면, networkidle이 보장하는 것이 무엇인지 다시 생각해볼 필요가 있다networkidle이 실제로 보장하는 것Playwright의 networkidle 상태는 정확히 하나만 보장한다> "500ms 이상 진행 중인 네트워크 요청이 없음"API 응답이 도착했다는 뜻이지, 그 응답으로 React가 DOM을 다 그렸다는 뜻이 아니다React SPA에서 데이터 흐름은 이렇게 진행된다1. fetch('/api/bench/123') ← 네트워크 요청2. 서버 응답 수신 ← networkidle이 이 시점을 감지3. setState({ data }) ← 클라이언트 사이드, 네트워크 없음4...

TIL/Claude Code 2026.04.20

[TIL][E2E] UI 선택 없이 언어를 전환하는 방법 — 쿠키 + URL 주입

E2E 자동화에서 언어 전환은 생각보다 자주 깨진다헤더의 글로브 아이콘을 찾고, 드롭다운을 열고, "Korean"을 선택하는 흐름은 직관적으로 보이지만 실제로는 취약 지점이 많다모달이 버튼을 가리면 실패하고, UI 구조가 바뀌면 로케이터가 무효화된다이번에 70줄 JS sibling 탐색을 15줄 쿠키 주입으로 교체하면서 왜 UI 조작 방식이 근본적으로 불안정한지, 그리고 어떻게 해결했는지 정리한다문제: 70줄짜리 JS evaluate가 필요했던 이유로그인 직후 앱이 영어로 표시되는 경우가 있었다. URL에 /en/이 포함된 상태였다언어 전환 버튼을 선택하기 위해 다음 흐름을 구현했다:1. 헤더에서 아바타 버튼(button:has(p))의 부모 컨테이너 찾기2. JS evaluate로 형제(sibling)..

TIL/Claude Code 2026.04.18
반응형