Sig Select: regression spec — re-ready restarts the visual countdown (client bisection)

A diagnostic that replays the reported "cancel → re-ready doesn't restart the
flashing numeral" sequence purely through the client handlers (countdown_start →
countdown_cancel → countdown_start). It passes: _showCountdown re-renders the
numeral every time the event is received, so the client logic is sound.

This bisects the live bug to WS *delivery* (the re-ready countdown_start not
reaching the browser), not client state — consistent with a dropped room socket
that never reconnected (every subsequent live event lost until a refresh, which
matches the symptom exactly). The auto-reconnect added in a6ce207 is the
relevant mitigation; kept as a permanent guard on the client restart path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Disco DeDisco
2026-06-05 14:54:26 -04:00
parent a6ce20761b
commit 44bf4e626c
2 changed files with 38 additions and 0 deletions

View File

@@ -919,6 +919,25 @@ describe("SigSelect", () => {
takeSigBtn = document.getElementById("id_take_sig_btn");
expect(takeSigBtn.textContent).toBe("WAIT NVM");
});
it("re-renders the numeral when countdown_start arrives again after a cancel", () => {
// Diagnostic for the re-ready bug: cancel → re-ready must restart the
// visual countdown. This exercises the CLIENT handler chain only; if
// it passes, the live failure is WS delivery (socket / broadcast), not
// client logic.
makeFixture({ reservations: '{"42":"PC"}', ready: true, countdownRemaining: 9 });
takeSigBtn = document.getElementById("id_take_sig_btn");
expect(takeSigBtn.textContent).toBe("9"); // counting
window.dispatchEvent(new CustomEvent("room:countdown_cancel", {
detail: { polarity: "levity", seconds_remaining: 7 },
}));
expect(takeSigBtn.textContent).toBe("WAIT NVM"); // cancelled
window.dispatchEvent(new CustomEvent("room:countdown_start", {
detail: { polarity: "levity", seconds: 7 },
}));
expect(takeSigBtn.textContent).toBe("7"); // restarted
expect(takeSigBtn.classList.contains("sig-take-sig-btn--counting")).toBe(true);
});
});
// ── polarity_room_done → tray sequence ─────────────────────────────────── //

View File

@@ -919,6 +919,25 @@ describe("SigSelect", () => {
takeSigBtn = document.getElementById("id_take_sig_btn");
expect(takeSigBtn.textContent).toBe("WAIT NVM");
});
it("re-renders the numeral when countdown_start arrives again after a cancel", () => {
// Diagnostic for the re-ready bug: cancel → re-ready must restart the
// visual countdown. This exercises the CLIENT handler chain only; if
// it passes, the live failure is WS delivery (socket / broadcast), not
// client logic.
makeFixture({ reservations: '{"42":"PC"}', ready: true, countdownRemaining: 9 });
takeSigBtn = document.getElementById("id_take_sig_btn");
expect(takeSigBtn.textContent).toBe("9"); // counting
window.dispatchEvent(new CustomEvent("room:countdown_cancel", {
detail: { polarity: "levity", seconds_remaining: 7 },
}));
expect(takeSigBtn.textContent).toBe("WAIT NVM"); // cancelled
window.dispatchEvent(new CustomEvent("room:countdown_start", {
detail: { polarity: "levity", seconds: 7 },
}));
expect(takeSigBtn.textContent).toBe("7"); // restarted
expect(takeSigBtn.classList.contains("sig-take-sig-btn--counting")).toBe(true);
});
});
// ── polarity_room_done → tray sequence ─────────────────────────────────── //