121 lines
4.2 KiB
GDScript
121 lines
4.2 KiB
GDScript
extends SceneTree
|
|
|
|
const MainScene = preload("res://main.tscn")
|
|
const SETTINGS_PATH := "user://aetherbound_guild_settings.json"
|
|
|
|
var failures: Array[String] = []
|
|
|
|
|
|
func _initialize() -> void:
|
|
call_deferred("run_test")
|
|
|
|
|
|
func run_test() -> void:
|
|
root.content_scale_mode = Window.CONTENT_SCALE_MODE_CANVAS_ITEMS
|
|
# Single target size (owner policy): every screen is authored at 1280x720.
|
|
root.content_scale_aspect = Window.CONTENT_SCALE_ASPECT_KEEP
|
|
root.content_scale_size = Vector2i(1280, 720)
|
|
root.size = Vector2i(1280, 720)
|
|
_cleanup()
|
|
var game = MainScene.instantiate()
|
|
game.audio_enabled = false
|
|
root.add_child(game)
|
|
await _frames(50)
|
|
var shell = game.entry_shell
|
|
expect(shell != null and shell.current_screen == "boot", "normal launch creates the entry shell")
|
|
# The boot screen dwells on its verification pass; wait for the handoff
|
|
# instead of assuming a fixed frame budget.
|
|
var apply: Button = await _wait_for_node(shell, "SetupApply")
|
|
await _touch(apply)
|
|
expect(shell.current_screen == "title", "parsed ScreenTouch applies first launch and reaches Title")
|
|
var settings_button: Button = shell.find_child("TitleSettings", true, false)
|
|
await _touch(settings_button)
|
|
expect(shell.current_screen == "settings", "parsed ScreenTouch opens Settings")
|
|
var language_category: Button = shell.find_child("SettingsCategory_language", true, false)
|
|
await _touch(language_category)
|
|
var locale_button: Button = shell.find_child("SettingLocale", true, false)
|
|
await _touch(locale_button)
|
|
var apply_settings: Button = shell.find_child("SettingsApply", true, false)
|
|
await _touch(apply_settings)
|
|
var back: Button = shell.find_child("SettingsBack", true, false)
|
|
await _touch(back)
|
|
expect(shell.current_screen == "title" and shell.settings.locale == "en", "locale applies and Back returns to Title")
|
|
await _release_scene(game)
|
|
|
|
var restarted = MainScene.instantiate()
|
|
restarted.audio_enabled = false
|
|
root.add_child(restarted)
|
|
await _frames(50)
|
|
var restarted_title := await _wait_for_node(restarted.entry_shell, "TitleSafeArea")
|
|
expect(restarted_title != null and restarted.entry_shell.current_screen == "title", "restart skips completed first launch")
|
|
await _release_scene(restarted)
|
|
_cleanup()
|
|
var reset_game = MainScene.instantiate()
|
|
reset_game.audio_enabled = false
|
|
root.add_child(reset_game)
|
|
await _frames(50)
|
|
var reset_setup := await _wait_for_node(reset_game.entry_shell, "FirstLaunchResponsiveLayout")
|
|
expect(reset_setup != null, "settings reset restores first-launch setup")
|
|
await _release_scene(reset_game)
|
|
_cleanup()
|
|
if failures.is_empty():
|
|
print("ABG_DEV1_ENTRY_TOUCH_OK parsed_screen_touch=true boot_setup_title_settings_apply_back=true restart=title reset=first_launch")
|
|
quit(0)
|
|
else:
|
|
for failure in failures:
|
|
push_error(failure)
|
|
quit(1)
|
|
|
|
|
|
func _release_scene(scene: Node) -> void:
|
|
# Release the synthesized SFX stream while the tree is still alive; freeing
|
|
# it during teardown races the audio server and leaks the generator playback.
|
|
var facade = scene.get("facade")
|
|
if facade != null:
|
|
var adapter = facade.get("audio_adapter")
|
|
if adapter != null:
|
|
adapter.cleanup()
|
|
scene.queue_free()
|
|
await _frames(20)
|
|
|
|
|
|
func _touch(control: Control) -> void:
|
|
var center := root.get_final_transform() * control.get_global_rect().get_center()
|
|
var press := InputEventScreenTouch.new()
|
|
press.position = center
|
|
press.pressed = true
|
|
press.index = 0
|
|
Input.parse_input_event(press)
|
|
await _frames(2)
|
|
var release := InputEventScreenTouch.new()
|
|
release.position = center
|
|
release.pressed = false
|
|
release.index = 0
|
|
Input.parse_input_event(release)
|
|
await _frames(4)
|
|
|
|
|
|
func _wait_for_node(shell: Node, node_name: String, max_frames := 600) -> Node:
|
|
for _i in range(max_frames):
|
|
var node := shell.find_child(node_name, true, false)
|
|
if node != null:
|
|
return node
|
|
await process_frame
|
|
return null
|
|
|
|
|
|
func _frames(count: int) -> void:
|
|
for frame in range(count):
|
|
await process_frame
|
|
|
|
|
|
func _cleanup() -> void:
|
|
for path in [SETTINGS_PATH, "%s.bak" % SETTINGS_PATH, "%s.candidate" % 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 entry touch: %s" % message)
|