반응형

전체 글 284

[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

[TIL][Shell] pytest 좀비 프로세스를 잡는 Watchdog 스크립트

출근해서 노트북을 켜는데, 노트북에서 비행기가 날아가면서 금세 뜨거워졌다 2026-04-04(금) 새벽부터 2026-04-06(월) 오후까지, pytest 프로세스 4개가 49시간 동안 종료되지 않고 실행 중이었다 PID 58852 test_login_steps 금 05AM~ 누적 CPU 594분 91.5%PID 68916 test_login_steps 금 08AM~ 누적 CPU 405분 91.5%PID 65872 test_bench_steps 금 08AM~ 누적 CPU 411분 93.6%PID 89532 omics-horizon-backend 금 03AM~ 누적 CPU 468분 90.9%Load Average 9.15, 메모리 15G..

TIL/Claude Code 2026.04.16
반응형