Fix: Login/Register unreachable from the main menu -- no button opened it
Reported directly by the user playtesting the exported exe: Play was permanently disabled and there was no way to log in or register. Root cause: main_menu.tscn wired Play and Quit, but nothing was ever connected to _on_login_button_pressed()/_on_register_button_pressed() -- the AuthPanel, its form, and all its backend-calling logic were fully correct, just completely unreachable. The script's own top comment even said "(the existing Play/Quit buttons)" as if Play/Quit somehow doubled as login triggers, which they never did -- a sign nobody ever actually clicked through the running scene, only checked things at the API level. Fix: added a real AuthButtonsRow (LoginButton, RegisterButton) wired to the existing handlers, which now hide themselves once auth succeeds. Also fixed grab_focus() targeting the AuthPanel (which can't accept focus, just a background warning) to focus the username field instead. Verified via two new smoke tests (smoke_test_main_menu_ui.gd, smoke_test_main_menu_full_flow.gd) using a *real signal emission* on the buttons, not a direct method call -- that distinction is exactly what would have caught the original bug. Full click-through confirmed against a real backend: open register form, fill it, submit, Play actually becomes enabled, welcome message shows, auth buttons hide. Also documents a real headless-testing gotcha found while verifying this: a synthetic Button.pressed.emit() on an await-using handler doesn't reliably get driven forward in --script/SceneTree mode the way real GUI input dispatch does -- confirmed by comparing direct-call vs emit() behavior side by side. Not a bug in the actual click-driven flow, a test-harness quirk to route around (call the handler directly, awaited, instead of emitting the signal). Full checkpoint suite re-verified clean on this branch: migrations, 68/68 pytest, all 6 Godot smoke tests (including the 2 new ones, picked up automatically by run_checkpoint_tests.py's glob). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
extends SceneTree
|
||||
## Verifies the main menu's Login/Register buttons actually open the auth
|
||||
## panel via a real signal emission (not calling the handler method
|
||||
## directly) -- that's the exact gap that shipped without ever being
|
||||
## caught: the AuthPanel and its logic were all correct, but nothing in
|
||||
## the scene was ever wired to open it.
|
||||
|
||||
|
||||
func _initialize() -> void:
|
||||
_run()
|
||||
|
||||
|
||||
func _run() -> void:
|
||||
await process_frame
|
||||
|
||||
var passed := 0
|
||||
var failed := 0
|
||||
|
||||
var packed: PackedScene = load("res://scenes/main_menu.tscn")
|
||||
var instance: Control = packed.instantiate()
|
||||
root.add_child(instance)
|
||||
await process_frame
|
||||
|
||||
var login_button: Button = instance.get_node("CenterContainer/VBoxContainer/AuthButtonsRow/LoginButton")
|
||||
var register_button: Button = instance.get_node("CenterContainer/VBoxContainer/AuthButtonsRow/RegisterButton")
|
||||
var auth_panel: PanelContainer = instance.get_node("CenterContainer/VBoxContainer/AuthPanel")
|
||||
|
||||
if _check("auth panel starts hidden", not auth_panel.visible):
|
||||
passed += 1
|
||||
else:
|
||||
failed += 1
|
||||
|
||||
login_button.pressed.emit()
|
||||
await process_frame
|
||||
|
||||
if _check("auth panel visible after a real LoginButton press signal", auth_panel.visible):
|
||||
passed += 1
|
||||
else:
|
||||
failed += 1
|
||||
|
||||
# Reset and check RegisterButton independently too.
|
||||
auth_panel.visible = false
|
||||
register_button.pressed.emit()
|
||||
await process_frame
|
||||
|
||||
if _check("auth panel visible after a real RegisterButton press signal", auth_panel.visible):
|
||||
passed += 1
|
||||
else:
|
||||
failed += 1
|
||||
|
||||
print("\n=== SMOKE RESULT: %d/%d passed ===" % [passed, passed + failed])
|
||||
quit(0 if failed == 0 else 1)
|
||||
|
||||
|
||||
func _check(description: String, condition: bool) -> bool:
|
||||
if condition:
|
||||
print(" PASS: ", description)
|
||||
else:
|
||||
printerr(" FAIL: ", description)
|
||||
return condition
|
||||
Reference in New Issue
Block a user