refactoring

This commit is contained in:
2026-05-02 16:24:42 +09:00
parent 296adf3073
commit 859c39fe0c
194 changed files with 5267 additions and 0 deletions

118
automation/defense_popup.py Normal file
View File

@@ -0,0 +1,118 @@
"""
automation/defense_popup.py — 수비 팝업 조작
수비 버튼 클릭, 수비 시퀀스 입력, 실책 수비 팝업 처리.
"""
from __future__ import annotations
from typing import Any
from playwright.sync_api import Page
from core.config_loader import defense_button_id_map, position_number_map
from core.field_calculator import (
extract_defense_sequence,
extract_error_position,
infer_error_position_fallback,
is_throwing_error,
)
from automation.page_helpers import get_last_visible_locator
def click_defense_button_robustly(page: Page, position: str, click_count: int = 1) -> bool:
"""수비 포지션 버튼을 안정적으로 클릭
ID 기반 → value 기반 → label 기반 순서로 시도
"""
btn_map = defense_button_id_map()
pos_num = position_number_map()
# 1) ID 기반
button_selector = btn_map.get(position)
if button_selector:
loc = page.locator(button_selector)
if loc.count() > 0:
for _ in range(click_count):
loc.click(force=True)
page.wait_for_timeout(60)
return True
# 2) value 기반
value = pos_num.get(position)
if value:
loc = page.locator(f"input[name='defenseNumberBtn'][value='{value}']")
if loc.count() > 0:
for _ in range(click_count):
loc.click(force=True)
page.wait_for_timeout(60)
return True
# 3) label 기반
all_buttons = page.locator("input[name='defenseNumberBtn']").all()
for btn in all_buttons:
label = (btn.get_attribute("id") or "").lower()
if position in label or label in position:
for _ in range(click_count):
btn.click(force=True)
page.wait_for_timeout(60)
return True
return False
def clear_defense_selections(page: Page) -> None:
"""수비 선택 초기화"""
page.evaluate(
"""() => {
document.querySelectorAll("input[name='defenseNumberBtn']").forEach(btn => {
btn.checked = false;
});
}"""
)
def click_defense_sequence_in_popup(
page: Page,
sequence: list[str],
complete_button_selector: str | None = None,
) -> None:
"""수비 시퀀스 순서대로 클릭 후 완료 버튼 클릭"""
for position in sequence:
click_defense_button_robustly(page, position)
page.wait_for_timeout(80)
if complete_button_selector:
btn = get_last_visible_locator(page, complete_button_selector)
if btn:
btn.click()
page.wait_for_timeout(120)
def fill_runner_out_defense(
page: Page, text: str, sequence_override: list[str] | None = None,
) -> None:
"""주루 아웃 수비 팝업 처리"""
page.wait_for_timeout(300)
sequence = sequence_override or extract_defense_sequence(text)
if sequence:
click_defense_sequence_in_popup(page, sequence)
def fill_error_defense_popup(page: Page, text: str) -> None:
"""실책 수비 팝업 처리"""
defense_sequence = extract_defense_sequence(text)
if len(defense_sequence) >= 2:
click_defense_sequence_in_popup(page, defense_sequence)
else:
error_position = extract_error_position(text)
if not error_position:
error_position = infer_error_position_fallback(text)
click_count = 2 if is_throwing_error(text) else 1
click_defense_button_robustly(page, error_position, click_count)
complete_button = get_last_visible_locator(page, "#btnNext")
if complete_button is None:
complete_button = get_last_visible_locator(page, "#btnAdd")
if complete_button:
complete_button.click()
page.wait_for_timeout(120)