반응형

전체 글 286

[TIL][CI] 실패 메일은 오는데 Slack 알림이 안 온다 — if: always() 가 안 지켜주는 경우

GitHub Actions 로 E2E 를 매일 돌리고, 결과를 Slack 으로 받는다 어느 날부터 실패 메일은 오는데 Slack 이 조용했다 [Run failed: E2E Core Test - main]E2E Core Test: All jobs have failedFailed in 30 minutes and 27 seconds메일이 온다는 건 워크플로우가 돌긴 돌았다는 뜻이다 그런데 워크플로우 안에 있는 Slack 스텝은 왜 안 갔을까 스텝 상태를 조회해 봤다✅ Run core tests success (25분)✅ Get Allure history success (109초)✅ Generate Allure Report ..

TIL/Claude Code 2026.09.12

[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
반응형