netfishing/tests/title_credits_validation.gd

208 lines
6.3 KiB
GDScript3
Raw Permalink Normal View History

extends SceneTree
const TitleScreenScene := preload("res://ui/title_screen.tscn")
const TitleCreditsPageType = preload("res://ui/title_credits_page.gd")
var _failures: Array[String] = []
func _initialize() -> void:
_run.call_deferred()
func _run() -> void:
var original_size: Vector2i = root.size
root.size = Vector2i(1280, 720)
var title_screen := TitleScreenScene.instantiate() as TitleScreen
root.add_child(title_screen)
await process_frame
await process_frame
var credits_button := title_screen.get_node(
"%CreditsButton"
) as BubbleButton
var credits_page := title_screen.get_node(
"%CreditsPage"
) as TitleCreditsPageType
var back_button: Button = credits_page.get_back_button()
var presentation := title_screen.get_node("%Center") as Control
var bubble_field := title_screen.get_node("%BubbleField") as Control
title_screen.call("_update_title_layout")
(title_screen.get_node("%ButtonCenter") as Control).show()
bubble_field.show()
title_screen.call("_set_title_bubbles_interactive", true)
await process_frame
_expect(credits_button != null, "title menu exposes a credits button")
_expect(credits_page != null, "title screen contains the credits page")
_expect(not credits_page.visible, "credits page starts closed")
_expect(
Rect2(Vector2.ZERO, bubble_field.size).encloses(
Rect2(credits_button.position, credits_button.size)
),
"credits bubble stays inside the authored title field",
)
_expect(
credits_button.mouse_filter == Control.MOUSE_FILTER_STOP,
"credits bubble accepts pointer input",
)
if OS.has_environment("NETFISHING_TITLE_MENU_CAPTURE"):
(title_screen.get_node("%StartPromptCenter") as Control).hide()
title_screen.set_process(true)
await create_timer(0.5).timeout
_expect(
_save_capture(
OS.get_environment("NETFISHING_TITLE_MENU_CAPTURE")
) == OK,
"title menu validation capture saves successfully",
)
title_screen.set_process(false)
title_screen.set("_navigation_focus_active", false)
credits_button.pressed.emit()
await process_frame
_expect(credits_page.visible, "pointer activation opens credits")
_expect(not presentation.visible, "credits replace the primary title menu")
_expect(
root.gui_get_focus_owner() != back_button,
"pointer activation does not pseudo-select back",
)
await create_timer(0.25).timeout
_expect(
credits_page.mouse_filter == Control.MOUSE_FILTER_PASS,
"credits page becomes pointer-interactive after entry motion",
)
_expect(
back_button.mouse_filter == Control.MOUSE_FILTER_STOP,
"credits back button accepts pointer clicks",
)
if OS.has_environment("NETFISHING_CREDITS_CAPTURE"):
await process_frame
_expect(
_save_capture(
OS.get_environment("NETFISHING_CREDITS_CAPTURE")
) == OK,
"credits validation capture saves successfully",
)
back_button.pressed.emit()
await process_frame
_expect(not credits_page.visible, "pointer back closes credits")
_expect(presentation.visible, "closing credits restores the title menu")
_expect(
root.gui_get_focus_owner() == null,
"pointer return leaves the title menu unfocused",
)
title_screen.set("_navigation_focus_active", true)
credits_button.grab_focus()
credits_button.pressed.emit()
await process_frame
await process_frame
_expect(
root.gui_get_focus_owner() == back_button,
"keyboard or controller activation focuses the credits back button",
)
var pointer_motion := InputEventMouseMotion.new()
pointer_motion.position = Vector2(640.0, 360.0)
title_screen._input(pointer_motion)
await process_frame
_expect(
root.gui_get_focus_owner() == null,
"pointer motion clears credits navigation focus",
)
var navigate := InputEventAction.new()
navigate.action = &"ui_down"
navigate.pressed = true
title_screen._input(navigate)
await process_frame
_expect(
root.gui_get_focus_owner() == back_button,
"navigation input restores credits focus",
)
var cancel := InputEventAction.new()
cancel.action = &"ui_cancel"
cancel.pressed = true
title_screen._input(cancel)
await process_frame
_expect(not credits_page.visible, "ui cancel closes credits")
_expect(
root.gui_get_focus_owner() == credits_button,
"navigation return restores focus to the credits bubble",
)
var chillnfill_name := credits_page.get_node(
"Paper/Margin/Layout/Columns/CreativeCredits/ChillnfillName"
) as Label
var voyager_name := credits_page.get_node(
"Paper/Margin/Layout/Columns/CreativeCredits/VoyagerName"
) as Label
var endeavour_name := credits_page.get_node(
"Paper/Margin/Layout/Columns/CreativeCredits/EndeavourName"
) as Label
var chillnfill_credit := credits_page.get_node(
"Paper/Margin/Layout/Columns/CreativeCredits/ChillnfillCredit"
) as Label
var tekgator_name := credits_page.get_node(
"Paper/Margin/Layout/Columns/CreativeCredits/TekgatorName"
) as Label
var tekgator_credit := credits_page.get_node(
"Paper/Margin/Layout/Columns/CreativeCredits/TekgatorCredit"
) as Label
var creative_credits := credits_page.get_node(
"Paper/Margin/Layout/Columns/CreativeCredits"
) as VBoxContainer
_expect(voyager_name.text == "Voyager", "in-game credits use Voyager")
_expect(
endeavour_name.text == "Endeavour",
"in-game credits use Endeavour",
)
_expect(
chillnfill_name.text == "chillnfill",
"in-game credits name chillnfill",
)
_expect(
"trees and bridges" in chillnfill_credit.text.to_lower(),
"in-game credits describe the supplied model families",
)
_expect(
tekgator_name.text == "Tekgator",
"in-game credits name Tekgator",
)
_expect(
"shop icon" in tekgator_credit.text.to_lower(),
"in-game credits describe Tekgator's shop icon artwork",
)
_expect(
Rect2(Vector2.ZERO, creative_credits.size).encloses(
Rect2(tekgator_credit.position, tekgator_credit.size)
),
"Tekgator's credit stays inside the authored credits column",
)
title_screen.queue_free()
root.size = original_size
await process_frame
await process_frame
if _failures.is_empty():
print("Title credits validation: PASS")
quit(0)
return
for failure: String in _failures:
push_error(failure)
quit(1)
func _expect(condition: bool, message: String) -> void:
if not condition:
_failures.append(message)
func _save_capture(path: String) -> Error:
var viewport_texture: Texture2D = root.get_texture()
if viewport_texture == null:
return ERR_UNAVAILABLE
return viewport_texture.get_image().save_png(path)