""" Automated unit & integration test for Resolution Scaling and Relative Coordinates. Tests that detect_state, OCR, and chest scanning correctly recognize all screens at 4K, 1440p, 1080p, and 720p resolutions. """ import json import os import cv2 from bot_core import DirtyLeagueBot, GameState import ocr_utils CONFIG_PATH = "config.json" with open(CONFIG_PATH, "r", encoding="utf-8") as f: config = json.load(f) bot = DirtyLeagueBot(config) SNAPSHOTS = { "IN_GAME (Battle)": ("assets/battle_screen_snapshot.png", GameState.IN_GAME), "IN_GAME (Leave)": ("assets/leave_screen_snapshot.png", GameState.IN_GAME), "TOWER_LOBBY": ("assets/tower_screen_snapshot.png", GameState.TOWER_LOBBY), "DEFEAT_SCREEN": ("assets/defeat_screen_snapshot.png", GameState.DEFEAT_SCREEN), "VICTORY_SCREEN": ("assets/victory_screen_snapshot.png", GameState.VICTORY_SCREEN), "NO_FREE_SLOTS": ("assets/no_free_slots_snapshot.png", GameState.NO_FREE_SLOTS_SCREEN), "CHEST_OPEN": ("assets/chest_reward_snapshot.png", GameState.CHEST_OPEN_SCREEN), } RESOLUTIONS = [ ("Native 4K", 3840, 2050), ("2K / 1440p", 2560, 1366), ("FullHD / 1080p", 1920, 1025), ("HD / 720p", 1280, 683), ] def run_tests(): print("=" * 70) print(" TESTING RESOLUTION INDEPENDENCE AND RELATIVE COORDINATES ") print("=" * 70) total_passed = 0 total_tests = 0 for res_name, target_w, target_h in RESOLUTIONS: print(f"\n--- Testing at resolution: {res_name} ({target_w}x{target_h}) ---") for screen_name, (path, expected_state) in SNAPSHOTS.items(): if not os.path.exists(path): print(f"[SKIP] Snapshot not found: {path}") continue orig_img = cv2.imread(path) if orig_img.shape[1] == target_w and orig_img.shape[0] == target_h: tested_frame = orig_img else: tested_frame = cv2.resize(orig_img, (target_w, target_h), interpolation=cv2.INTER_AREA) detected = bot.detect_state(tested_frame) is_ok = (detected == expected_state) status_str = "PASS" if is_ok else "FAIL" print(f" [{status_str}] {screen_name:18} -> detected: {detected.value:20} (expected: {expected_state.value})") total_tests += 1 if is_ok: total_passed += 1 # Test OCR across resolutions print("\n--- Testing OCR Scaling ---") tower_4k = cv2.imread("assets/tower_screen_snapshot.png") for res_name, target_w, target_h in RESOLUTIONS: frame = cv2.resize(tower_4k, (target_w, target_h), interpolation=cv2.INTER_AREA) trophies = ocr_utils.ocr_reader.read_trophies(frame) is_ok = (trophies == (1925, 2300)) status_str = "PASS" if is_ok else "FAIL" print(f" [{status_str}] {res_name:14} Trophies OCR: {trophies} (expected: (1925, 2300))") total_tests += 1 if is_ok: total_passed += 1 # Test Crown Chest Badge (5/5) across resolutions print("\n--- Testing Crown Chest 5/5 Badge Scaling ---") crown_4k = cv2.imread("assets/tower_lobby_crown_filled.png") for res_name, target_w, target_h in RESOLUTIONS: frame = cv2.resize(crown_4k, (target_w, target_h), interpolation=cv2.INTER_AREA) crown = ocr_utils.ocr_reader.read_crown_chest(frame) is_ok = (crown == (5, 5)) status_str = "PASS" if is_ok else "FAIL" print(f" [{status_str}] {res_name:14} Crown 5/5 Badge: {crown} (expected: (5, 5))") total_tests += 1 if is_ok: total_passed += 1 # Test Bottom Chests Grid across resolutions print("\n--- Testing Bottom Chests Grid Scanning ---") for res_name, target_w, target_h in RESOLUTIONS: frame = cv2.resize(tower_4k, (target_w, target_h), interpolation=cv2.INTER_AREA) chests = bot.scan_bottom_chests(frame) statuses = {k: v["status"] for k, v in chests.items()} # Slots 1 and 3 are OPEN on tower_screen_snapshot is_ok = (statuses[1] == "OPEN" and statuses[3] == "OPEN") status_str = "PASS" if is_ok else "FAIL" print(f" [{status_str}] {res_name:14} Chests: {statuses}") total_tests += 1 if is_ok: total_passed += 1 print("\n" + "=" * 70) print(f" TOTAL RESULT: {total_passed} / {total_tests} tests passed ({total_passed / total_tests * 100:.1f}%)") print("=" * 70) assert total_passed == total_tests, f"Only {total_passed}/{total_tests} tests passed!" if __name__ == "__main__": run_tests()