fixed open #id_tray obscuring role select FTs
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
Disco DeDisco
2026-03-29 23:46:23 -04:00
parent fb782cf5ef
commit 299a806862
2 changed files with 20 additions and 18 deletions

View File

@@ -1,4 +1,8 @@
var RoleSelect = (function () { var RoleSelect = (function () {
// Set to true by handleTurnChanged so that a WS turn_changed that races
// ahead of the fetch response doesn't get overridden by Tray.open().
var _turnChangedBeforeFetch = false;
var ROLES = [ var ROLES = [
{ code: "PC", name: "Player", element: "Fire" }, { code: "PC", name: "Player", element: "Fire" },
{ code: "BC", name: "Builder", element: "Stone" }, { code: "BC", name: "Builder", element: "Stone" },
@@ -24,6 +28,7 @@ var RoleSelect = (function () {
} }
function selectRole(roleCode, cardEl) { function selectRole(roleCode, cardEl) {
_turnChangedBeforeFetch = false; // fresh selection, reset the race flag
var invCard = cardEl.cloneNode(true); var invCard = cardEl.cloneNode(true);
invCard.classList.add("flipped"); invCard.classList.add("flipped");
// strip old event listeners from the clone by replacing with a clean copy // strip old event listeners from the clone by replacing with a clean copy
@@ -70,7 +75,8 @@ var RoleSelect = (function () {
trayCard.dataset.role = roleCode; trayCard.dataset.role = roleCode;
grid.insertBefore(trayCard, grid.firstChild); grid.insertBefore(trayCard, grid.firstChild);
} }
if (typeof Tray !== "undefined") { // Only open if turn_changed hasn't already arrived and closed it.
if (typeof Tray !== "undefined" && !_turnChangedBeforeFetch) {
Tray.open(); Tray.open();
} }
} }
@@ -164,6 +170,8 @@ var RoleSelect = (function () {
if (invSlot) invSlot.innerHTML = ""; if (invSlot) invSlot.innerHTML = "";
// Force-close tray instantly so it never obscures the next player's card-stack. // Force-close tray instantly so it never obscures the next player's card-stack.
// Also set the race flag so the fetch .then() doesn't re-open if it arrives late.
_turnChangedBeforeFetch = true;
if (typeof Tray !== "undefined") Tray.forceClose(); if (typeof Tray !== "undefined") Tray.forceClose();
var stack = document.querySelector(".card-stack[data-user-slots]"); var stack = document.querySelector(".card-stack[data-user-slots]");

View File

@@ -772,35 +772,32 @@ class RoleSelectChannelsTest(ChannelsFunctionalTest):
By.CSS_SELECTOR, ".card-stack[data-state='eligible']" By.CSS_SELECTOR, ".card-stack[data-state='eligible']"
)) ))
# Select a role — tray opens and card lands in topmost square. # Select a role — card lands in topmost grid square.
self.browser.find_element(By.CSS_SELECTOR, ".card-stack").click() self.browser.find_element(By.CSS_SELECTOR, ".card-stack").click()
self.wait_for(lambda: self.browser.find_element(By.ID, "id_role_select")) self.wait_for(lambda: self.browser.find_element(By.ID, "id_role_select"))
self.browser.find_element(By.CSS_SELECTOR, "#id_role_select .card").click() self.browser.find_element(By.CSS_SELECTOR, "#id_role_select .card").click()
self.confirm_guard() self.confirm_guard()
self.wait_for(lambda: self.assertTrue( # Wait for fetch .then() — card must be first child of grid.
self.browser.execute_script("return Tray.isOpen()") self.wait_for(lambda: self.assertTrue(self.browser.execute_script("""
))
is_first = self.browser.execute_script("""
var card = document.querySelector('#id_tray_grid .tray-role-card'); var card = document.querySelector('#id_tray_grid .tray-role-card');
return card !== null && card === card.parentElement.firstElementChild; return card !== null && card === card.parentElement.firstElementChild;
""") """)))
self.assertTrue(is_first, "Role card should be first child (topmost) of grid")
# Turn advances via WS — seat 2 becomes active. # Turn advances via WS — seat 2 becomes active.
self.wait_for(lambda: self.browser.find_element( self.wait_for(lambda: self.browser.find_element(
By.CSS_SELECTOR, ".table-seat.active[data-slot='2']" By.CSS_SELECTOR, ".table-seat.active[data-slot='2']"
)) ))
# Tray must be closed after turn_changed. # Tray must be closed: forceClose() fires in handleTurnChanged.
self.assertFalse( self.assertFalse(
self.browser.execute_script("return Tray.isOpen()"), self.browser.execute_script("return Tray.isOpen()"),
"Tray should be closed after turn advances" "Tray should be closed after turn advances"
) )
def test_landscape_tray_closes_on_turn_advance(self): def test_landscape_tray_closes_on_turn_advance(self):
"""Landscape: same sequence — role card at leftmost grid square; tray """Landscape: role card at leftmost grid square; tray closes when
closes when turn_changed arrives.""" turn_changed arrives via WS."""
self.browser.set_window_size(844, 390) self.browser.set_window_size(844, 390)
room_url = self._make_turn_test_room() room_url = self._make_turn_test_room()
self.create_pre_authenticated_session("founder@test.io") self.create_pre_authenticated_session("founder@test.io")
@@ -814,21 +811,18 @@ class RoleSelectChannelsTest(ChannelsFunctionalTest):
self.browser.find_element(By.CSS_SELECTOR, "#id_role_select .card").click() self.browser.find_element(By.CSS_SELECTOR, "#id_role_select .card").click()
self.confirm_guard() self.confirm_guard()
self.wait_for(lambda: self.assertTrue( # Wait for fetch .then() — card must be first child of grid.
self.browser.execute_script("return Tray.isOpen()") self.wait_for(lambda: self.assertTrue(self.browser.execute_script("""
))
is_first = self.browser.execute_script("""
var card = document.querySelector('#id_tray_grid .tray-role-card'); var card = document.querySelector('#id_tray_grid .tray-role-card');
return card !== null && card === card.parentElement.firstElementChild; return card !== null && card === card.parentElement.firstElementChild;
""") """)))
self.assertTrue(is_first, "Role card should be first child (leftmost) of grid")
# Turn advances via WS — seat 2 becomes active. # Turn advances via WS — seat 2 becomes active.
self.wait_for(lambda: self.browser.find_element( self.wait_for(lambda: self.browser.find_element(
By.CSS_SELECTOR, ".table-seat.active[data-slot='2']" By.CSS_SELECTOR, ".table-seat.active[data-slot='2']"
)) ))
# Tray must be closed after turn_changed. # Tray must be closed.
self.assertFalse( self.assertFalse(
self.browser.execute_script("return Tray.isOpen()"), self.browser.execute_script("return Tray.isOpen()"),
"Tray should be closed after turn advances" "Tray should be closed after turn advances"