kdrug-inventory-system/test_compound_e2e.py
시골약사 a4861dc1b8 fix: 조제 관리 약재 추가 시 마스터 약재명 표시 및 2단계 선택 구조 개선
- 약재 추가 드롭다운에서 제품명 대신 마스터 약재명 표시
- /api/herbs/masters 엔드포인트 사용하여 ingredient_code 기반 약재 목록 로드
- /api/herbs/by-ingredient/<code> 엔드포인트 추가 (제품 목록 조회)
- 2단계 선택 구조: 약재(마스터) → 제품 → 원산지/롯트
- 기존 처방 약재와 새로 추가하는 약재의 테이블 구조 통일 (6칼럼)
- 원산지 선택 칼럼에 제품/원산지 드롭다운 함께 표시

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-15 18:31:15 +00:00

201 lines
8.3 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
E2E 테스트: 조제 화면에서 쌍화탕 선택 후 인삼 선택 가능 확인
"""
from playwright.sync_api import sync_playwright, expect
import time
def test_compound_ginseng_selection():
"""쌍화탕 조제 시 인삼 선택 가능 테스트"""
with sync_playwright() as p:
# 브라우저 실행 (headless 모드)
browser = p.chromium.launch(headless=True)
page = browser.new_page()
try:
print("=" * 80)
print("E2E 테스트: 쌍화탕 조제 시 인삼 선택 가능 확인")
print("=" * 80)
# 1. 메인 페이지 접속
print("\n[1] 메인 페이지 접속...")
page.goto('http://localhost:5001')
page.wait_for_load_state('networkidle')
print("✓ 페이지 로드 완료")
# 2. 조제관리 메뉴 클릭
print("\n[2] 조제관리 메뉴 클릭...")
# 사이드바에서 조제 관리 클릭
compound_menu = page.locator('text=조제 관리').first
compound_menu.click()
time.sleep(2)
print("✓ 조제관리 화면 진입")
# 조제 입력 섹션 표시
print("\n[2-1] 조제 입력 섹션 표시...")
show_compound_entry = page.locator('#showCompoundEntry')
if show_compound_entry.count() > 0:
show_compound_entry.click()
time.sleep(1)
print("✓ 조제 입력 섹션 표시")
# 3. 현재 화면 상태 확인
print("\n[3] 화면 상태 확인...")
# 스크린샷 저장
page.screenshot(path='/tmp/compound_screen_after_menu_click.png')
print("✓ 스크린샷: /tmp/compound_screen_after_menu_click.png")
# 페이지에 select 요소가 있는지 확인
all_selects = page.locator('select').all()
print(f"✓ 페이지 내 select 요소: {len(all_selects)}")
for idx, sel in enumerate(all_selects):
sel_id = sel.get_attribute('id')
sel_name = sel.get_attribute('name')
print(f" [{idx}] id={sel_id}, name={sel_name}")
# 처방 선택 시도
print("\n[4] 처방 선택...")
# compoundFormula select 요소 찾기 (ID로 정확히)
formula_select = page.locator('#compoundFormula')
if formula_select.count() > 0:
# select가 visible 될 때까지 기다리기
try:
formula_select.wait_for(state="visible", timeout=5000)
except:
print("⚠️ 처방 선택 드롭다운이 보이지 않음")
# 옵션 확인
options = formula_select.locator('option').all()
print(f"✓ 드롭다운 옵션: {len(options)}")
for opt in options:
print(f" - {opt.text_content()}")
# 쌍화탕 선택
try:
formula_select.select_option(label='쌍화탕')
time.sleep(3)
print("✓ 쌍화탕 선택 완료")
except Exception as e:
print(f"⚠️ label로 선택 실패: {e}")
# index로 시도 (첫 번째 옵션은 보통 placeholder이므로 index=1)
try:
formula_select.select_option(index=1)
time.sleep(3)
print("✓ 첫 번째 처방 선택 완료")
except Exception as e2:
print(f"❌ 처방 선택 실패: {e2}")
else:
print("❌ 처방 드롭다운을 찾을 수 없음")
# 5. 약재 추가 버튼 클릭
print("\n[5] 약재 추가 버튼 클릭...")
# 약재 추가 버튼 찾기
add_ingredient_btn = page.locator('#addIngredientBtn')
if add_ingredient_btn.count() > 0:
add_ingredient_btn.click()
time.sleep(1)
print("✓ 약재 추가 버튼 클릭 완료")
# 6. 새로 추가된 행에서 약재 선택 드롭다운 확인
print("\n[6] 약재 선택 드롭다운 확인...")
# 새로 추가된 행 찾기 (마지막 행)
new_row = page.locator('#compoundIngredients tr').last
# 약재 선택 드롭다운 찾기
herb_select = new_row.locator('.herb-select-compound')
if herb_select.count() > 0:
print("✓ 약재 선택 드롭다운 발견")
# 드롭다운 옵션 확인
time.sleep(1) # 드롭다운이 로드될 시간 확보
options = herb_select.locator('option').all()
print(f"✓ 약재 옵션: {len(options)}")
# 처음 10개 옵션 출력
for idx, option in enumerate(options[:10]):
text = option.text_content()
value = option.get_attribute('value')
print(f" [{idx}] {text} (value: {value})")
# 마스터 약재명이 표시되는지 확인
has_master_names = False
for option in options:
text = option.text_content()
# ingredient_code 형식의 value와 한글/한자 형식의 텍스트 확인
if '(' in text and ')' in text: # 한자 포함 형식
has_master_names = True
break
if has_master_names:
print("\n✅ 마스터 약재명이 드롭다운에 표시됨!")
# 인삼 선택 시도
try:
herb_select.select_option(label='인삼 (人蔘)')
print("✓ 인삼 선택 완료")
except:
# label이 정확히 일치하지 않으면 부분 매칭
for idx, option in enumerate(options):
if '인삼' in option.text_content():
herb_select.select_option(index=idx)
print(f"✓ 인삼 선택 완료 (index {idx})")
break
time.sleep(1)
# 제품 선택 드롭다운 확인
product_select = new_row.locator('.product-select')
if product_select.count() > 0:
print("\n[7] 제품 선택 드롭다운 확인...")
time.sleep(1) # 제품 목록 로드 대기
product_options = product_select.locator('option').all()
print(f"✓ 제품 옵션: {len(product_options)}")
for idx, option in enumerate(product_options):
print(f" [{idx}] {option.text_content()}")
else:
print("\n⚠️ 마스터 약재명 대신 제품명이 드롭다운에 표시됨")
print("(신흥생강, 신흥작약 등의 제품명이 보임)")
else:
print("❌ 약재 선택 드롭다운을 찾을 수 없음")
else:
print("❌ 약재 추가 버튼을 찾을 수 없음")
# 7. 최종 스크린샷
page.screenshot(path='/tmp/compound_screen_final.png')
print("\n✓ 최종 스크린샷: /tmp/compound_screen_final.png")
print("\n" + "=" * 80)
print("테스트 완료")
print("=" * 80)
# 완료
time.sleep(1)
except Exception as e:
print(f"\n❌ 에러 발생: {e}")
import traceback
traceback.print_exc()
# 에러 스크린샷
page.screenshot(path='/tmp/compound_error.png')
print("에러 스크린샷: /tmp/compound_error.png")
finally:
browser.close()
if __name__ == '__main__':
test_compound_ginseng_selection()