extends SceneTree const EntryShell = preload("res://entry/entry_shell.gd") const SettingsStore = preload("res://entry/settings_store.gd") const SAVE_PATH := "user://aetherbound_guild_p10_3.json" const SETTINGS_PATH := "user://dev1_title_settings_test.json" var failures: Array[String] = [] func _initialize() -> void: call_deferred("run_test") func run_test() -> void: _cleanup() await verify_no_save_and_return_paths() await verify_resumable_state() _cleanup() if failures.is_empty(): print("ABG_DEV1_TITLE_OK new_game=true continue_missing=disabled continue_valid=enabled settings_return=true credits_return=true exit_review=true frozen_routes=explained") quit(0) else: for failure in failures: push_error(failure) quit(1) func verify_no_save_and_return_paths() -> void: var shell = await _shell() var continue_button: Button = shell.get_node("TitleSafeArea/TitleLayout/TitleCopy/TitleActions/TitleContinue") var new_game: Button = shell.get_node("TitleSafeArea/TitleLayout/TitleCopy/TitleActions/TitleNewGame") expect(continue_button.disabled, "Continue is disabled when no save exists") expect(new_game.has_focus(), "New Game owns the initial keyboard/controller focus") expect(shell.get_node_or_null("TitleSafeArea/TitleLayout/TitleHeader/TitleHeaderChrome") != null, "Title uses the enamel guild header") expect(shell.get_node_or_null("TitleSafeArea/TitleLayout/TitleHeader/TitleGuildBanner/TitleGuildBannerChrome") != null, "Title header carries a heraldic banner") expect(shell.get_node_or_null("TitleSafeArea/TitleLayout/TitleCommandDock/TitleCommandDockChrome") != null, "Title actions attach to the command dock") expect(new_game.get_node_or_null("Chrome") != null and continue_button.get_node_or_null("Chrome") != null, "Title actions use authored icon chrome") expect(shell.get_node("TitleSafeArea/TitleLayout/TitleTools/TitleSettings").get_node_or_null("Chrome") != null, "Title utility controls use the ivory tool treatment") expect(not shell.get_node("TitleSafeArea/TitleLayout/TitleCopy/TitleContinueReason").text.is_empty(), "disabled Continue has a visible reason") shell.open_new_game_boundary() await process_frame expect("DEV-2" in shell.get_node("TitleSafeArea/TitleLayout/TitleCopy/TitleNotice").text, "New Game names the frozen DEV-2 boundary without changing a save") shell.show_settings_placeholder() await process_frame expect(shell.current_screen == "settings", "Settings opens from Title") shell.back_to_title() await process_frame expect(shell.current_screen == "title", "Settings returns exactly to Title") shell.show_credits_placeholder() await process_frame shell.back_to_title() await process_frame expect(shell.current_screen == "title", "Credits returns exactly to Title") shell.request_exit() await process_frame expect(shell.current_screen == "exit_review" and shell.get_node_or_null("ChildSafeArea/ChildLayout/ExitConfirm") != null, "Back boundary uses an exit review") shell.queue_free() await process_frame func verify_resumable_state() -> void: _write(SAVE_PATH, JSON.stringify({"save_kind": "aetherbound_guild_p10_3", "save_version": 9})) var shell = await _shell() var continue_button: Button = shell.get_node("TitleSafeArea/TitleLayout/TitleCopy/TitleActions/TitleContinue") expect(not continue_button.disabled, "Continue enables for a structurally valid local save") shell.open_continue_boundary() await process_frame expect("unchanged" in shell.get_node("TitleSafeArea/TitleLayout/TitleCopy/TitleNotice").text, "Continue preserves the save and explains the later resume review") shell.queue_free() await process_frame func _shell(): var shell = EntryShell.new() shell.auto_start = false root.add_child(shell) await process_frame shell.settings = SettingsStore.new().defaults() shell.settings.setup_completed = true shell.settings.locale = "en" shell.show_title() await process_frame return shell func _write(path: String, text: String) -> void: var file := FileAccess.open(path, FileAccess.WRITE) file.store_string(text) file.close() func _cleanup() -> void: for path in [SAVE_PATH, SETTINGS_PATH]: if FileAccess.file_exists(path): DirAccess.remove_absolute(path) func expect(condition: bool, message: String) -> void: if not condition: failures.append("DEV-1 Title: %s" % message)