106 lines
3.3 KiB
Python
106 lines
3.3 KiB
Python
"""
|
|
Controlled single-cycle integration test:
|
|
Runs 1 full cycle starting from TOWER_LOBBY:
|
|
1. Detect TOWER_LOBBY
|
|
2. Read trophies and chests
|
|
3. Enter Fight
|
|
4. Handle IN_GAME until outcome (Victory / Defeat / Surrender)
|
|
5. Handle Result screen (Collect / OK / Remove chest if no slots)
|
|
6. Verify clean return to TOWER_LOBBY
|
|
"""
|
|
|
|
import json
|
|
import logging
|
|
import sys
|
|
import time
|
|
from bot_core import DirtyLeagueBot, GameState
|
|
|
|
logging.basicConfig(
|
|
level=logging.INFO,
|
|
format="%(asctime)s [%(levelname)s] %(message)s",
|
|
handlers=[logging.StreamHandler(sys.stdout)]
|
|
)
|
|
|
|
|
|
def run_single_cycle_test(timeout_sec: int = 180):
|
|
with open("config.json", "r", encoding="utf-8") as f:
|
|
config = json.load(f)
|
|
|
|
bot = DirtyLeagueBot(config)
|
|
logging.info("=== Starting Controlled Full Cycle Test ===")
|
|
logging.info(f"Timeout: {timeout_sec}s. Press Ctrl+C to abort.")
|
|
|
|
start_time = time.time()
|
|
initial_lobby_confirmed = False
|
|
in_game_reached = False
|
|
result_handled = False
|
|
cycle_complete = False
|
|
|
|
while time.time() - start_time < timeout_sec:
|
|
frame = bot.wm.capture_frame(client_only=True)
|
|
|
|
# 1. Global offer popup check
|
|
if bot.check_and_dismiss_offer_popup(frame):
|
|
time.sleep(1.0)
|
|
continue
|
|
|
|
state = bot.detect_state(frame)
|
|
|
|
if state != bot.state:
|
|
logging.info(f"[FSM TRANSITION] {bot.state.value} -> {state.value}")
|
|
bot.state = state
|
|
|
|
if state == GameState.TOWER_LOBBY:
|
|
if not initial_lobby_confirmed:
|
|
logging.info("[STEP 1] Confirmed TOWER_LOBBY start.")
|
|
initial_lobby_confirmed = True
|
|
bot.handle_lobby(frame)
|
|
elif in_game_reached and result_handled:
|
|
logging.info("[SUCCESS] Successfully completed full cycle and returned to TOWER_LOBBY!")
|
|
cycle_complete = True
|
|
break
|
|
else:
|
|
# If we are still in lobby before entering game, try handle_lobby again
|
|
bot.handle_lobby(frame)
|
|
|
|
elif state == GameState.IN_GAME:
|
|
in_game_reached = True
|
|
bot.handle_in_game(frame)
|
|
|
|
elif state == GameState.VICTORY_SCREEN:
|
|
logging.info("[STEP] Handling VICTORY_SCREEN...")
|
|
bot.handle_victory(frame)
|
|
result_handled = True
|
|
|
|
elif state == GameState.DEFEAT_SCREEN:
|
|
logging.info("[STEP] Handling DEFEAT_SCREEN...")
|
|
bot.handle_defeat(frame)
|
|
result_handled = True
|
|
|
|
elif state == GameState.NO_FREE_SLOTS_SCREEN:
|
|
logging.info("[STEP] Handling NO_FREE_SLOTS_SCREEN...")
|
|
bot.handle_no_free_slots(frame)
|
|
result_handled = True
|
|
|
|
elif state == GameState.CHEST_OPEN_SCREEN:
|
|
logging.info("[STEP] Handling CHEST_OPEN_SCREEN...")
|
|
bot.handle_chest_open_screen(frame)
|
|
|
|
elif state == GameState.MAIN_MENU:
|
|
logging.info("[STEP] Handling MAIN_MENU...")
|
|
bot.handle_main_menu(frame)
|
|
|
|
time.sleep(bot.poll_interval)
|
|
|
|
elapsed = time.time() - start_time
|
|
if cycle_complete:
|
|
logging.info(f"=== FULL CYCLE TEST PASSED in {elapsed:.1f}s ===")
|
|
return True
|
|
else:
|
|
logging.warning(f"=== TEST TIMEOUT or INTERRUPTED after {elapsed:.1f}s ===")
|
|
return False
|
|
|
|
|
|
if __name__ == "__main__":
|
|
run_single_cycle_test()
|