extends SceneTree const EntryShell = preload("res://entry/entry_shell.gd") const SettingsStore = preload("res://entry/settings_store.gd") const SIZES := [Vector2i(1280, 720)] var failures: Array[String] = [] func _initialize() -> void: call_deferred("run_test") func run_test() -> void: var viewport := SubViewport.new() viewport.size = SIZES[0] viewport.render_target_update_mode = SubViewport.UPDATE_ALWAYS root.add_child(viewport) var shell := EntryShell.new() shell.auto_start = false viewport.add_child(shell) await _frames(3) shell.settings = SettingsStore.new().defaults() shell.settings.locale = "zh_CN" shell.settings.text_scale = 1.3 shell.setup_draft = shell.settings.duplicate(true) shell.show_first_launch() await _frames(4) for viewport_size in SIZES: viewport.size = viewport_size await _frames(3) _verify_layout(shell, viewport_size) viewport.queue_free() await _frames(4) if failures.is_empty(): print("ABG_DEV1_FIRST_LAUNCH_RESPONSIVE_OK sizes=1280x720 preview=bounded settings=stretch rows=min48 apply=stretch resize=true") quit(0) else: for failure in failures: push_error(failure) quit(1) func _verify_layout(shell: Control, viewport_size: Vector2i) -> void: var bounds := Rect2(Vector2.ZERO, Vector2(viewport_size)) var world := shell.find_child("FirstLaunchWorld", true, false) as Control var preview := shell.find_child("FirstLaunchPreviewFrame", true, false) as Control var panel := shell.find_child("FirstLaunchControls", true, false) as Control var apply := shell.find_child("SetupApply", true, false) as Control expect(world != null and preview != null and panel != null and apply != null, "%dx%d First-launch layers exist" % [viewport_size.x, viewport_size.y]) if world == null or preview == null or panel == null or apply == null: return expect(world.get_global_rect().is_equal_approx(bounds), "%dx%d world fills viewport" % [viewport_size.x, viewport_size.y]) expect(bounds.encloses(preview.get_global_rect()), "%dx%d preview remains inside viewport" % [viewport_size.x, viewport_size.y]) expect(bounds.encloses(panel.get_global_rect()), "%dx%d settings panel remains inside viewport" % [viewport_size.x, viewport_size.y]) expect(apply.get_global_rect().size.y >= 52.0, "%dx%d Apply keeps command height" % [viewport_size.x, viewport_size.y]) for node_name in ["SetupLanguage", "SetupSafeArea", "SetupTextScale", "SetupReducedMotion", "SetupReducedFlashes", "SetupCaptions"]: var row := shell.find_child(node_name, true, false) as Control expect(row != null and row.get_global_rect().size.y >= 48.0 and bounds.encloses(row.get_global_rect()), "%dx%d %s keeps 48 px row and bounds" % [viewport_size.x, viewport_size.y, node_name]) func _frames(count: int) -> void: for frame in range(count): await process_frame func expect(condition: bool, message: String) -> void: if not condition: failures.append("DEV-1 First-launch responsive: %s" % message)