Fix flaky regression test for Play->Back session persistence
The actual fix (main_menu.gd's _ready() checking ApiClient.has_token() and restoring authenticated state via get_me()) was already correct -- verified this directly by instrumenting frame-by-frame state and seeing it resolve properly in ~5 frames. The test wrapping it was the real problem: _wait_for_menu_ready() only waited 2 frames total before checking assertions, nowhere near enough for a real HTTP round-trip, so every run failed on a fix that actually worked. Root fix: added a real auth_state_ready signal to main_menu.gd, emitted once _ready()'s session check has actually resolved (either branch -- authenticated or logged-out). The test now awaits that signal directly instead of guessing from a frame count or from UI properties that are ambiguous mid-await (AuthButtonsRow.visible is true both before the check resolves AND in a genuine logged-out end state, which is exactly what made an earlier polling-based fix attempt here also flaky). Also fixed a second real bug in the test itself: unique_id used Time.get_ticks_msec() (process-relative, not wall-clock), colliding with a previous run's still-present data -- same flakiness class fixed elsewhere this session, same fix (wall-clock ms + random suffix). Verified: 12/12 passing across 3 consecutive runs against a real backend. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -45,7 +45,8 @@ func _run() -> void:
|
||||
return
|
||||
|
||||
# 1. Establish a real, valid session exactly the way a user would.
|
||||
var unique_id := Time.get_ticks_msec()
|
||||
randomize()
|
||||
var unique_id: int = int(Time.get_unix_time_from_system() * 1000) + randi() % 100000
|
||||
var username := USERNAME % unique_id
|
||||
var email := EMAIL % unique_id
|
||||
print("\n=== Setup: register ", username, " ===")
|
||||
@@ -59,13 +60,21 @@ func _run() -> void:
|
||||
# 2. First visit to the main menu: should already show the authenticated
|
||||
# state (no login form, Play enabled).
|
||||
change_scene_to_file("res://scenes/main_menu.tscn")
|
||||
await _wait_for_menu_ready()
|
||||
# change_scene_to_file defers the actual swap -- a couple frames is
|
||||
# plenty for the scene object itself to exist (unlike the real
|
||||
# get_me() network round-trip afterward, which is what auth_state_ready
|
||||
# actually waits for below).
|
||||
for i in 5:
|
||||
await process_frame
|
||||
if current_scene is Control:
|
||||
break
|
||||
|
||||
var menu: Control = current_scene
|
||||
if menu == null or not menu is Control:
|
||||
printerr("FAIL: main_menu.tscn did not become current_scene")
|
||||
_finish()
|
||||
return
|
||||
await menu.auth_state_ready
|
||||
_check("first main menu visit restores authenticated state", _is_authenticated(menu))
|
||||
|
||||
# 3. Play -> world_list.tscn (real button press).
|
||||
@@ -90,6 +99,12 @@ func _run() -> void:
|
||||
_finish()
|
||||
return
|
||||
|
||||
# The new main_menu instance's own _ready() is *also* awaiting a real
|
||||
# get_me() call -- _wait_for_scene_change only confirms the scene
|
||||
# object exists, not that its authenticated-state fields have been
|
||||
# set yet. Wait for the real signal, not a guess.
|
||||
await menu.auth_state_ready
|
||||
|
||||
# 5. THE regression assertion: still logged in after returning.
|
||||
_check("main menu stays authenticated after Play -> Back", _is_authenticated(menu))
|
||||
|
||||
@@ -113,18 +128,6 @@ func _is_authenticated(menu: Control) -> bool:
|
||||
and not auth_panel.visible
|
||||
|
||||
|
||||
## Wait for the main menu's _ready() to finish, including its awaited
|
||||
## ApiClient.get_me() call (which is why we wait several frames).
|
||||
func _wait_for_menu_ready() -> void:
|
||||
for i in 20:
|
||||
await process_frame
|
||||
if current_scene is Control:
|
||||
# The menu's _ready() awaits get_me(); give it time to resolve.
|
||||
if i >= 1:
|
||||
return
|
||||
await process_frame
|
||||
|
||||
|
||||
func _wait_for_scene_change(previous_scene: Node) -> void:
|
||||
for i in 20:
|
||||
await process_frame
|
||||
|
||||
Reference in New Issue
Block a user