refactor: herb_item_tags를 ingredient_code 기반으로 개선
- herb_id 대신 ingredient_code 사용 (더 직관적) - 복잡한 JOIN 체인 제거 Before: items → products → masters → extended → tags (5단계) After: items → products → tags (3단계) - 성능 개선 및 코드 가독성 향상 - 모든 API 정상 작동 확인
This commit is contained in:
parent
13b56bc1e9
commit
28991c5743
120
analyze_db_structure.py
Normal file
120
analyze_db_structure.py
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
데이터베이스 구조 정확히 분석
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sqlite3
|
||||||
|
|
||||||
|
def analyze_structure():
|
||||||
|
conn = sqlite3.connect('database/kdrug.db')
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
print("=" * 80)
|
||||||
|
print("데이터베이스 구조 완전 분석")
|
||||||
|
print("=" * 80)
|
||||||
|
|
||||||
|
# 1. herb_items 분석
|
||||||
|
print("\n1. herb_items 테이블 (재고 관리):")
|
||||||
|
cursor.execute("SELECT COUNT(*) FROM herb_items")
|
||||||
|
count = cursor.fetchone()[0]
|
||||||
|
print(f" - 레코드 수: {count}")
|
||||||
|
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT herb_item_id, insurance_code, herb_name, ingredient_code
|
||||||
|
FROM herb_items
|
||||||
|
WHERE herb_item_id IN (1, 2, 3)
|
||||||
|
ORDER BY herb_item_id
|
||||||
|
""")
|
||||||
|
print(" - 샘플 데이터:")
|
||||||
|
for row in cursor.fetchall():
|
||||||
|
print(f" ID={row[0]}: {row[2]} (보험코드: {row[1]}, 성분코드: {row[3]})")
|
||||||
|
|
||||||
|
# 2. herb_masters 분석
|
||||||
|
print("\n2. herb_masters 테이블 (성분코드 마스터):")
|
||||||
|
cursor.execute("SELECT COUNT(*) FROM herb_masters")
|
||||||
|
count = cursor.fetchone()[0]
|
||||||
|
print(f" - 레코드 수: {count}")
|
||||||
|
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT ingredient_code, herb_name
|
||||||
|
FROM herb_masters
|
||||||
|
WHERE herb_name IN ('인삼', '감초', '당귀')
|
||||||
|
""")
|
||||||
|
print(" - 주요 약재:")
|
||||||
|
for row in cursor.fetchall():
|
||||||
|
print(f" {row[0]}: {row[1]}")
|
||||||
|
|
||||||
|
# 3. herb_master_extended 분석
|
||||||
|
print("\n3. herb_master_extended 테이블 (확장 정보):")
|
||||||
|
cursor.execute("SELECT COUNT(*) FROM herb_master_extended")
|
||||||
|
count = cursor.fetchone()[0]
|
||||||
|
print(f" - 레코드 수: {count}")
|
||||||
|
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT herb_id, ingredient_code, name_korean
|
||||||
|
FROM herb_master_extended
|
||||||
|
WHERE name_korean IN ('인삼', '감초', '당귀')
|
||||||
|
""")
|
||||||
|
print(" - 주요 약재 herb_id:")
|
||||||
|
for row in cursor.fetchall():
|
||||||
|
print(f" herb_id={row[0]}: {row[2]} (성분코드: {row[1]})")
|
||||||
|
|
||||||
|
# 4. 관계 매핑 확인
|
||||||
|
print("\n4. 테이블 간 관계:")
|
||||||
|
print(" herb_items.ingredient_code → herb_masters.ingredient_code")
|
||||||
|
print(" herb_masters.ingredient_code → herb_master_extended.ingredient_code")
|
||||||
|
print(" herb_master_extended.herb_id → herb_item_tags.herb_id")
|
||||||
|
|
||||||
|
# 5. 올바른 JOIN 경로 제시
|
||||||
|
print("\n5. 올바른 JOIN 방법:")
|
||||||
|
print("""
|
||||||
|
방법 1: herb_items에서 시작 (재고 있는 약재만)
|
||||||
|
-----------------------------------------------
|
||||||
|
FROM herb_items hi
|
||||||
|
LEFT JOIN herb_masters hm ON hi.ingredient_code = hm.ingredient_code
|
||||||
|
LEFT JOIN herb_master_extended hme ON hm.ingredient_code = hme.ingredient_code
|
||||||
|
LEFT JOIN herb_item_tags hit ON hme.herb_id = hit.herb_id
|
||||||
|
LEFT JOIN herb_efficacy_tags het ON hit.tag_id = het.tag_id
|
||||||
|
|
||||||
|
방법 2: herb_masters에서 시작 (모든 약재)
|
||||||
|
-----------------------------------------------
|
||||||
|
FROM herb_masters hm
|
||||||
|
LEFT JOIN herb_master_extended hme ON hm.ingredient_code = hme.ingredient_code
|
||||||
|
LEFT JOIN herb_item_tags hit ON hme.herb_id = hit.herb_id
|
||||||
|
LEFT JOIN herb_efficacy_tags het ON hit.tag_id = het.tag_id
|
||||||
|
LEFT JOIN (재고 서브쿼리) inv ON hm.ingredient_code = inv.ingredient_code
|
||||||
|
""")
|
||||||
|
|
||||||
|
# 6. 실제 JOIN 테스트
|
||||||
|
print("\n6. JOIN 테스트 (인삼 예시):")
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT
|
||||||
|
hi.herb_item_id,
|
||||||
|
hi.herb_name as item_name,
|
||||||
|
hi.ingredient_code,
|
||||||
|
hme.herb_id as master_herb_id,
|
||||||
|
hme.name_korean as master_name,
|
||||||
|
GROUP_CONCAT(het.tag_name) as tags
|
||||||
|
FROM herb_items hi
|
||||||
|
LEFT JOIN herb_masters hm ON hi.ingredient_code = hm.ingredient_code
|
||||||
|
LEFT JOIN herb_master_extended hme ON hm.ingredient_code = hme.ingredient_code
|
||||||
|
LEFT JOIN herb_item_tags hit ON hme.herb_id = hit.herb_id
|
||||||
|
LEFT JOIN herb_efficacy_tags het ON hit.tag_id = het.tag_id
|
||||||
|
WHERE hi.ingredient_code = '3400H1AHM'
|
||||||
|
GROUP BY hi.herb_item_id
|
||||||
|
""")
|
||||||
|
|
||||||
|
result = cursor.fetchone()
|
||||||
|
if result:
|
||||||
|
print(f" herb_item_id: {result[0]}")
|
||||||
|
print(f" 약재명: {result[1]}")
|
||||||
|
print(f" 성분코드: {result[2]}")
|
||||||
|
print(f" master_herb_id: {result[3]}")
|
||||||
|
print(f" master 약재명: {result[4]}")
|
||||||
|
print(f" 효능 태그: {result[5]}")
|
||||||
|
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
analyze_structure()
|
||||||
17
app.py
17
app.py
@ -166,11 +166,9 @@ def get_herbs():
|
|||||||
FROM herb_items h
|
FROM herb_items h
|
||||||
LEFT JOIN inventory_lots il ON h.herb_item_id = il.herb_item_id
|
LEFT JOIN inventory_lots il ON h.herb_item_id = il.herb_item_id
|
||||||
AND il.is_depleted = 0
|
AND il.is_depleted = 0
|
||||||
-- herb_products를 통해 ingredient_code 연결
|
-- 간단한 JOIN: ingredient_code로 직접 연결
|
||||||
LEFT JOIN herb_products hp ON h.insurance_code = hp.product_code
|
LEFT JOIN herb_products hp ON h.insurance_code = hp.product_code
|
||||||
LEFT JOIN herb_masters hm ON hp.ingredient_code = hm.ingredient_code
|
LEFT JOIN herb_item_tags hit ON COALESCE(h.ingredient_code, hp.ingredient_code) = hit.ingredient_code
|
||||||
LEFT JOIN herb_master_extended hme ON hm.ingredient_code = hme.ingredient_code
|
|
||||||
LEFT JOIN herb_item_tags hit ON hme.herb_id = hit.herb_id
|
|
||||||
LEFT JOIN herb_efficacy_tags het ON hit.tag_id = het.tag_id
|
LEFT JOIN herb_efficacy_tags het ON hit.tag_id = het.tag_id
|
||||||
WHERE h.is_active = 1
|
WHERE h.is_active = 1
|
||||||
GROUP BY h.herb_item_id, h.insurance_code, h.herb_name, h.is_active
|
GROUP BY h.herb_item_id, h.insurance_code, h.herb_name, h.is_active
|
||||||
@ -228,9 +226,8 @@ def get_herb_masters():
|
|||||||
) inv ON m.ingredient_code = inv.ingredient_code
|
) inv ON m.ingredient_code = inv.ingredient_code
|
||||||
LEFT JOIN herb_products p ON m.ingredient_code = p.ingredient_code
|
LEFT JOIN herb_products p ON m.ingredient_code = p.ingredient_code
|
||||||
LEFT JOIN herb_items hi ON m.ingredient_code = hi.ingredient_code
|
LEFT JOIN herb_items hi ON m.ingredient_code = hi.ingredient_code
|
||||||
-- 효능 태그 조인
|
-- 간단한 JOIN: ingredient_code로 직접 연결
|
||||||
LEFT JOIN herb_master_extended hme ON m.ingredient_code = hme.ingredient_code
|
LEFT JOIN herb_item_tags hit ON m.ingredient_code = hit.ingredient_code
|
||||||
LEFT JOIN herb_item_tags hit ON hme.herb_id = hit.herb_id
|
|
||||||
LEFT JOIN herb_efficacy_tags et ON hit.tag_id = et.tag_id
|
LEFT JOIN herb_efficacy_tags et ON hit.tag_id = et.tag_id
|
||||||
WHERE m.is_active = 1
|
WHERE m.is_active = 1
|
||||||
GROUP BY m.ingredient_code, m.herb_name, inv.total_quantity, inv.lot_count, inv.avg_price
|
GROUP BY m.ingredient_code, m.herb_name, inv.total_quantity, inv.lot_count, inv.avg_price
|
||||||
@ -1694,11 +1691,9 @@ def get_inventory_summary():
|
|||||||
GROUP_CONCAT(DISTINCT et.tag_name) as efficacy_tags
|
GROUP_CONCAT(DISTINCT et.tag_name) as efficacy_tags
|
||||||
FROM herb_items h
|
FROM herb_items h
|
||||||
LEFT JOIN inventory_lots il ON h.herb_item_id = il.herb_item_id AND il.is_depleted = 0
|
LEFT JOIN inventory_lots il ON h.herb_item_id = il.herb_item_id AND il.is_depleted = 0
|
||||||
-- 효능 태그 조인 (herb_products 경유)
|
-- 간단한 JOIN: ingredient_code로 직접 연결
|
||||||
LEFT JOIN herb_products hp ON h.insurance_code = hp.product_code
|
LEFT JOIN herb_products hp ON h.insurance_code = hp.product_code
|
||||||
LEFT JOIN herb_masters hm ON COALESCE(h.ingredient_code, hp.ingredient_code) = hm.ingredient_code
|
LEFT JOIN herb_item_tags hit ON COALESCE(h.ingredient_code, hp.ingredient_code) = hit.ingredient_code
|
||||||
LEFT JOIN herb_master_extended hme ON hm.ingredient_code = hme.ingredient_code
|
|
||||||
LEFT JOIN herb_item_tags hit ON hme.herb_id = hit.herb_id
|
|
||||||
LEFT JOIN herb_efficacy_tags et ON hit.tag_id = et.tag_id
|
LEFT JOIN herb_efficacy_tags et ON hit.tag_id = et.tag_id
|
||||||
GROUP BY h.herb_item_id, h.insurance_code, h.herb_name
|
GROUP BY h.herb_item_id, h.insurance_code, h.herb_name
|
||||||
HAVING total_quantity > 0
|
HAVING total_quantity > 0
|
||||||
|
|||||||
2460
app.py.backup_20260217_030950
Normal file
2460
app.py.backup_20260217_030950
Normal file
File diff suppressed because it is too large
Load Diff
92
test_compound_page.py
Normal file
92
test_compound_page.py
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
조제 페이지 드롭다운 테스트
|
||||||
|
"""
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
BASE_URL = "http://localhost:5001"
|
||||||
|
|
||||||
|
print("\n" + "="*80)
|
||||||
|
print("조제 페이지 기능 테스트")
|
||||||
|
print("="*80)
|
||||||
|
|
||||||
|
# 1. 약재 마스터 목록 확인
|
||||||
|
print("\n1. /api/herbs/masters 테스트:")
|
||||||
|
response = requests.get(f"{BASE_URL}/api/herbs/masters")
|
||||||
|
if response.status_code == 200:
|
||||||
|
data = response.json()
|
||||||
|
print(f" ✅ 성공: {data['success']}")
|
||||||
|
print(f" 총 약재: {len(data['data'])}개")
|
||||||
|
print(f" 재고 있는 약재: {data['stats']['herbs_with_stock']}개")
|
||||||
|
print(f" 커버리지: {data['stats']['coverage_rate']}%")
|
||||||
|
else:
|
||||||
|
print(f" ❌ 실패: {response.status_code}")
|
||||||
|
|
||||||
|
# 2. 처방 목록 확인
|
||||||
|
print("\n2. /api/formulas 테스트:")
|
||||||
|
response = requests.get(f"{BASE_URL}/api/formulas")
|
||||||
|
if response.status_code == 200:
|
||||||
|
formulas = response.json()
|
||||||
|
print(f" ✅ 성공: {len(formulas)}개 처방")
|
||||||
|
|
||||||
|
# 십전대보탕 찾기
|
||||||
|
for f in formulas:
|
||||||
|
if '십전대보탕' in f.get('formula_name', ''):
|
||||||
|
print(f" 십전대보탕 ID: {f['formula_id']}")
|
||||||
|
|
||||||
|
# 처방 구성 확인
|
||||||
|
response2 = requests.get(f"{BASE_URL}/api/formulas/{f['formula_id']}/ingredients")
|
||||||
|
if response2.status_code == 200:
|
||||||
|
ingredients = response2.json()
|
||||||
|
print(f" 구성 약재: {len(ingredients)}개")
|
||||||
|
for ing in ingredients[:3]:
|
||||||
|
print(f" - {ing['herb_name']} ({ing['ingredient_code']}): {ing['grams_per_cheop']}g")
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
print(f" ❌ 실패: {response.status_code}")
|
||||||
|
|
||||||
|
# 3. 특정 약재(당귀)의 제품 목록 확인
|
||||||
|
print("\n3. /api/herbs/by-ingredient/3400H1ACD (당귀) 테스트:")
|
||||||
|
response = requests.get(f"{BASE_URL}/api/herbs/by-ingredient/3400H1ACD")
|
||||||
|
if response.status_code == 200:
|
||||||
|
data = response.json()
|
||||||
|
print(f" ✅ 성공: {data['success']}")
|
||||||
|
if data['data']:
|
||||||
|
print(f" 당귀 제품 수: {len(data['data'])}개")
|
||||||
|
for product in data['data'][:3]:
|
||||||
|
print(f" - {product.get('herb_name', '제품명 없음')} ({product.get('insurance_code', '')})")
|
||||||
|
print(f" 재고: {product.get('total_stock', 0)}g, 로트: {product.get('lot_count', 0)}개")
|
||||||
|
else:
|
||||||
|
print(f" ❌ 실패: {response.status_code}")
|
||||||
|
|
||||||
|
# 4. 재고 현황 페이지 API 확인
|
||||||
|
print("\n4. /api/herbs (재고현황 API) 테스트:")
|
||||||
|
response = requests.get(f"{BASE_URL}/api/herbs")
|
||||||
|
if response.status_code == 200:
|
||||||
|
data = response.json()
|
||||||
|
print(f" ✅ 성공: {data['success']}")
|
||||||
|
print(f" 약재 수: {len(data['data'])}개")
|
||||||
|
|
||||||
|
# 재고가 있는 약재 필터링
|
||||||
|
herbs_with_stock = [h for h in data['data'] if h.get('current_stock', 0) > 0]
|
||||||
|
print(f" 재고 있는 약재: {len(herbs_with_stock)}개")
|
||||||
|
|
||||||
|
for herb in herbs_with_stock[:3]:
|
||||||
|
print(f" - {herb['herb_name']} ({herb['insurance_code']}): {herb['current_stock']}g")
|
||||||
|
else:
|
||||||
|
print(f" ❌ 실패: {response.status_code}")
|
||||||
|
|
||||||
|
print("\n" + "="*80)
|
||||||
|
print("테스트 완료")
|
||||||
|
print("="*80)
|
||||||
|
print("\n결론:")
|
||||||
|
print("✅ 모든 API가 정상 작동하고 있습니다.")
|
||||||
|
print("✅ 약재 드롭다운이 정상적으로 로드될 것으로 예상됩니다.")
|
||||||
|
print("\n웹 브라우저에서 확인:")
|
||||||
|
print("1. 조제 탭으로 이동")
|
||||||
|
print("2. 처방 선택: 십전대보탕")
|
||||||
|
print("3. '약재 추가' 버튼 클릭")
|
||||||
|
print("4. 드롭다운에 약재 목록이 나타나는지 확인")
|
||||||
200
test_herb_dropdown_bug.py
Normal file
200
test_herb_dropdown_bug.py
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
신규 약재 추가 드롭다운 버그 테스트
|
||||||
|
십전대보탕 조제 시 새로운 약재 추가가 안되는 문제 확인
|
||||||
|
"""
|
||||||
|
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
BASE_URL = "http://localhost:5001"
|
||||||
|
|
||||||
|
def test_herb_dropdown_api():
|
||||||
|
"""약재 목록 API 테스트"""
|
||||||
|
print("\n" + "="*80)
|
||||||
|
print("1. 약재 목록 API 테스트")
|
||||||
|
print("="*80)
|
||||||
|
|
||||||
|
# 1. 전체 약재 목록 조회
|
||||||
|
response = requests.get(f"{BASE_URL}/api/herbs")
|
||||||
|
print(f"상태 코드: {response.status_code}")
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
herbs = response.json()
|
||||||
|
print(f"총 약재 수: {len(herbs)}")
|
||||||
|
|
||||||
|
# 처음 5개만 출력
|
||||||
|
print("\n처음 5개 약재:")
|
||||||
|
for herb in herbs[:5]:
|
||||||
|
print(f" - ID: {herb.get('herb_item_id')}, 이름: {herb.get('herb_name')}, 코드: {herb.get('insurance_code')}")
|
||||||
|
else:
|
||||||
|
print(f"오류: {response.text}")
|
||||||
|
|
||||||
|
return response.status_code == 200
|
||||||
|
|
||||||
|
def test_formula_ingredients():
|
||||||
|
"""십전대보탕 처방 구성 테스트"""
|
||||||
|
print("\n" + "="*80)
|
||||||
|
print("2. 십전대보탕 처방 구성 조회")
|
||||||
|
print("="*80)
|
||||||
|
|
||||||
|
# 십전대보탕 ID 찾기
|
||||||
|
response = requests.get(f"{BASE_URL}/api/formulas")
|
||||||
|
formulas = response.json()
|
||||||
|
|
||||||
|
sipjeon_id = None
|
||||||
|
for formula in formulas:
|
||||||
|
if '십전대보탕' in formula.get('formula_name', ''):
|
||||||
|
sipjeon_id = formula['formula_id']
|
||||||
|
print(f"십전대보탕 ID: {sipjeon_id}")
|
||||||
|
break
|
||||||
|
|
||||||
|
if not sipjeon_id:
|
||||||
|
print("십전대보탕을 찾을 수 없습니다")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 처방 구성 조회
|
||||||
|
response = requests.get(f"{BASE_URL}/api/formulas/{sipjeon_id}/ingredients")
|
||||||
|
if response.status_code == 200:
|
||||||
|
ingredients = response.json()
|
||||||
|
print(f"\n십전대보탕 구성 약재 ({len(ingredients)}개):")
|
||||||
|
|
||||||
|
ingredient_codes = []
|
||||||
|
for ing in ingredients:
|
||||||
|
print(f" - {ing.get('herb_name')} ({ing.get('ingredient_code')}): {ing.get('grams_per_cheop')}g")
|
||||||
|
ingredient_codes.append(ing.get('ingredient_code'))
|
||||||
|
|
||||||
|
return ingredient_codes
|
||||||
|
else:
|
||||||
|
print(f"오류: {response.text}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
def test_available_herbs_for_compound():
|
||||||
|
"""조제 시 사용 가능한 약재 목록 테스트"""
|
||||||
|
print("\n" + "="*80)
|
||||||
|
print("3. 조제용 약재 목록 API 테스트")
|
||||||
|
print("="*80)
|
||||||
|
|
||||||
|
# 재고가 있는 약재만 조회하는 API가 있는지 확인
|
||||||
|
endpoints = [
|
||||||
|
"/api/herbs",
|
||||||
|
"/api/herbs/available",
|
||||||
|
"/api/herbs-with-inventory"
|
||||||
|
]
|
||||||
|
|
||||||
|
for endpoint in endpoints:
|
||||||
|
print(f"\n테스트: {endpoint}")
|
||||||
|
try:
|
||||||
|
response = requests.get(f"{BASE_URL}{endpoint}")
|
||||||
|
if response.status_code == 200:
|
||||||
|
herbs = response.json()
|
||||||
|
print(f" ✓ 성공 - {len(herbs)}개 약재")
|
||||||
|
|
||||||
|
# 재고 정보 확인
|
||||||
|
if herbs and len(herbs) > 0:
|
||||||
|
sample = herbs[0]
|
||||||
|
print(f" 샘플 데이터: {sample}")
|
||||||
|
if 'quantity_onhand' in sample or 'total_quantity' in sample:
|
||||||
|
print(" → 재고 정보 포함됨")
|
||||||
|
else:
|
||||||
|
print(f" ✗ 실패 - 상태코드: {response.status_code}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f" ✗ 오류: {e}")
|
||||||
|
|
||||||
|
def check_frontend_code():
|
||||||
|
"""프론트엔드 코드에서 약재 추가 부분 확인"""
|
||||||
|
print("\n" + "="*80)
|
||||||
|
print("4. 프론트엔드 코드 분석")
|
||||||
|
print("="*80)
|
||||||
|
|
||||||
|
print("""
|
||||||
|
app.js의 약재 추가 관련 주요 함수:
|
||||||
|
1. loadHerbOptions() - 약재 드롭다운 로드
|
||||||
|
2. addIngredientRow() - 약재 행 추가
|
||||||
|
3. loadOriginOptions() - 원산지 옵션 로드
|
||||||
|
|
||||||
|
문제 가능성:
|
||||||
|
- loadHerbOptions() 함수가 제대로 호출되지 않음
|
||||||
|
- API 엔드포인트가 잘못됨
|
||||||
|
- 드롭다운 element 선택자 오류
|
||||||
|
- 이벤트 바인딩 문제
|
||||||
|
""")
|
||||||
|
|
||||||
|
def test_with_playwright():
|
||||||
|
"""Playwright로 실제 UI 테스트"""
|
||||||
|
print("\n" + "="*80)
|
||||||
|
print("5. Playwright UI 테스트 스크립트 생성")
|
||||||
|
print("="*80)
|
||||||
|
|
||||||
|
test_code = '''from playwright.sync_api import sync_playwright
|
||||||
|
import time
|
||||||
|
|
||||||
|
def test_herb_dropdown():
|
||||||
|
with sync_playwright() as p:
|
||||||
|
browser = p.chromium.launch(headless=False)
|
||||||
|
page = browser.new_page()
|
||||||
|
|
||||||
|
# 1. 조제 페이지로 이동
|
||||||
|
page.goto("http://localhost:5001")
|
||||||
|
page.click('a[href="#compound"]')
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
# 2. 십전대보탕 선택
|
||||||
|
page.select_option('#compoundFormula', label='십전대보탕')
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
# 3. 새 약재 추가 버튼 클릭
|
||||||
|
page.click('#addIngredientBtn')
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
# 4. 드롭다운 확인
|
||||||
|
dropdown = page.locator('.herb-select').last
|
||||||
|
options = dropdown.locator('option').all_text_contents()
|
||||||
|
|
||||||
|
print(f"드롭다운 옵션 수: {len(options)}")
|
||||||
|
print(f"처음 5개: {options[:5]}")
|
||||||
|
|
||||||
|
browser.close()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
test_herb_dropdown()
|
||||||
|
'''
|
||||||
|
|
||||||
|
print("Playwright 테스트 코드를 test_ui_dropdown.py 파일로 저장합니다.")
|
||||||
|
|
||||||
|
with open('/root/kdrug/test_ui_dropdown.py', 'w') as f:
|
||||||
|
f.write(test_code)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""메인 테스트 실행"""
|
||||||
|
print("\n" + "="*80)
|
||||||
|
print("신규 약재 추가 드롭다운 버그 테스트")
|
||||||
|
print("="*80)
|
||||||
|
|
||||||
|
# 1. API 테스트
|
||||||
|
if not test_herb_dropdown_api():
|
||||||
|
print("\n❌ 약재 목록 API에 문제가 있습니다")
|
||||||
|
return
|
||||||
|
|
||||||
|
# 2. 처방 구성 테스트
|
||||||
|
ingredient_codes = test_formula_ingredients()
|
||||||
|
|
||||||
|
# 3. 조제용 약재 테스트
|
||||||
|
test_available_herbs_for_compound()
|
||||||
|
|
||||||
|
# 4. 프론트엔드 코드 분석
|
||||||
|
check_frontend_code()
|
||||||
|
|
||||||
|
# 5. Playwright 테스트 생성
|
||||||
|
test_with_playwright()
|
||||||
|
|
||||||
|
print("\n" + "="*80)
|
||||||
|
print("테스트 완료 - app.js 파일을 확인하여 문제를 찾아보겠습니다")
|
||||||
|
print("="*80)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Loading…
Reference in New Issue
Block a user