Files
stickman/tests/test_phase19_starter_chooser_layout.gd
ryan 59f1817063 Add StageBackgroundView and related tests for plain background functionality
- Implemented StageBackgroundView class for managing sky and plain backgrounds in the stage.
- Added functionality to set background type and color, bind camera, and apply themes.
- Created test_phase19_plain_background.gd to validate plain background behavior and migration.
- Developed test_phase19_starter_chooser_layout.gd to ensure proper layout and functionality of the starter chooser.
- Included visual capture tests for UI elements and interactions.
2026-10-22 16:18:25 -04:00

145 lines
6.5 KiB
GDScript

extends SceneTree
const SELECTOR_SCENE: PackedScene = preload("res://scenes/stage/asset_selector.tscn")
const SANDBOX_THEME_SCRIPT: Script = preload("res://scripts/stage/sandbox_theme.gd")
var _checks: int = 0
var _failures: int = 0
var _selector: AssetSelector
func _initialize() -> void:
call_deferred("_run")
func _run() -> void:
root.size = Vector2i(1280, 720)
_selector = SELECTOR_SCENE.instantiate() as AssetSelector
root.add_child(_selector)
await process_frame
var stage_theme: SandboxTheme = SANDBOX_THEME_SCRIPT.new() as SandboxTheme
stage_theme.load_from("res://sandbox_theme.json")
_selector.apply_theme(stage_theme)
_selector.open("starters", _starter_entries())
await process_frame
await process_frame
_test_roomy_layout()
await _save_capture("phase19_starter_chooser_wide.png")
await _test_hover_style_and_capture()
await _test_narrow_layout()
_selector.hide()
_selector.queue_free()
await process_frame
if _failures == 0:
print("RESULT: ALL PASSED (%d checks)" % _checks)
quit(0)
else:
print("RESULT: %d FAILURE(S) out of %d checks" % [_failures, _checks])
quit(1)
func _starter_entries() -> Array[Dictionary]:
return [
{
"id": "starter_plain_background",
"name": "Plain Background",
"description": "An empty stage with one color. Choose a new color whenever you like.",
"path": "res://content/stages/starters/plain_background.scene",
},
{
"id": "starter_blank_scene",
"name": "Open Sky",
"description": "An empty stage with a soft sky. Sun and clouds, ready for your story.",
"path": "res://content/stages/starters/blank.scene",
},
{
"id": "starter_town_street",
"name": "Town Street",
"description": "Cloudy sky, shops, trees, sidewalk, and road.",
"path": "res://content/stages/starters/town_street.scene",
},
{
"id": "starter_living_room",
"name": "Living Room",
"description": "A cozy room with a window, rug, and furniture.",
"path": "res://content/stages/starters/living_room.scene",
},
]
func _test_roomy_layout() -> void:
var grid: GridContainer = _grid()
var close_button: Button = _selector.find_child("CloseButton", true, false) as Button
_expect(_selector.size.x == 1160, "roomy starter chooser uses the preferred 1160-pixel width")
_expect(int(_selector.get("_active_columns")) == 2 and grid != null and grid.columns == 2, "roomy chooser presents two card columns")
_expect(close_button != null and close_button.visible and close_button.custom_minimum_size.y >= 44.0, "roomy chooser keeps its visible Close action reachable")
var first_card: Control = grid.get_child(0) as Control if grid != null and grid.get_child_count() > 0 else null
var preview: Control = first_card.find_child("StarterScenePreview", true, false) as Control if first_card != null else null
var viewport: SubViewport = preview.get_child(0) as SubViewport if preview != null and preview.get_child_count() > 0 else null
var preview_aspect: float = float(viewport.size.x) / float(viewport.size.y) if viewport != null and viewport.size.y > 0 else 0.0
_expect(first_card != null and first_card.custom_minimum_size.x >= 500.0, "roomy starter cards expand to at least 500 pixels")
_expect(preview != null and preview.custom_minimum_size.x >= 500.0 and preview.custom_minimum_size.y >= 240.0, "roomy previews meet the approved dimensions")
_expect(viewport != null and viewport.size.x >= 500 and viewport.size.y >= 240 and preview_aspect >= 1.9 and preview_aspect <= 2.2, "preview render target preserves the wide scene shape")
var title: Label = _selector.find_child("TitleLabel", true, false) as Label
_expect(title != null and title.visible and title.text == "Choose a starter scene", "roomy chooser keeps its readable title")
func _test_narrow_layout() -> void:
root.size = Vector2i(550, 690)
await process_frame
_selector.call("_update_popup_layout")
_selector.call("_rebuild")
await process_frame
await process_frame
var grid: GridContainer = _grid()
var close_button: Button = _selector.find_child("CloseButton", true, false) as Button
_expect(_selector.size.x <= root.size.x - 24, "narrow chooser stays within the safe screen margins")
_expect(int(_selector.get("_active_columns")) == 1 and grid != null and grid.columns == 1, "narrow chooser switches to a single card column")
_expect(int(_selector.get("_page_capacity")) == 4 and grid != null and grid.get_child_count() == 4, "narrow chooser keeps all four cards in the scrollable body")
_expect(close_button != null and close_button.visible, "narrow chooser keeps Close visible outside the scrolling body")
var first_card: Control = grid.get_child(0) as Control if grid != null and grid.get_child_count() > 0 else null
var preview: Control = first_card.find_child("StarterScenePreview", true, false) as Control if first_card != null else null
_expect(preview != null and preview.custom_minimum_size.x >= 400.0 and preview.custom_minimum_size.y >= 200.0, "narrow single-column layout retains large previews")
await _save_capture("phase19_starter_chooser_narrow.png")
func _test_hover_style_and_capture() -> void:
var grid: GridContainer = _grid()
var hover_card: Button = grid.get_child(1) as Button if grid != null and grid.get_child_count() > 1 else null
if hover_card == null:
_expect(false, "starter card is available for hover preview")
return
var hover_style: StyleBoxFlat = hover_card.get_theme_stylebox("hover") as StyleBoxFlat
_expect(hover_style != null and hover_style.border_color.is_equal_approx(Color("#22C6FF")), "starter hover style uses the EDIT blue border")
if hover_style == null:
return
var normal_style: StyleBox = hover_card.get_theme_stylebox("normal")
hover_card.add_theme_stylebox_override("normal", hover_style)
await process_frame
await _save_capture("phase19_starter_chooser_hover.png")
hover_card.add_theme_stylebox_override("normal", normal_style)
func _grid() -> GridContainer:
return _selector.find_child("GridContainer", true, false) as GridContainer
func _expect(condition: bool, message: String) -> void:
_checks += 1
if condition:
print("PASS: " + message)
else:
_failures += 1
push_error("Starter chooser layout check failed: " + message)
func _save_capture(file_name: String) -> void:
if DisplayServer.get_name() == "headless":
return
await RenderingServer.frame_post_draw
var capture: Image = root.get_texture().get_image()
var capture_dir: String = ProjectSettings.globalize_path("res://.phase19_captures")
DirAccess.make_dir_recursive_absolute(capture_dir)
var error: Error = capture.save_png(capture_dir.path_join(file_name))
_expect(error == OK, "capture saved for visual inspection: %s" % file_name)