FT fix CI #342: seed log_tax_debit in test_saved_draw_renders_brief_banner — @taxman ledger sprint left the FT stale
All checks were successful
ci/woodpecker/push/pyswiss Pipeline was successful
ci/woodpecker/push/main Pipeline was successful

CI pipeline #342 surfaced two errors, both on the same selector failure path:

1. `test_saved_draw_renders_brief_banner_with_next_free_draw_timestamp` (test_game_my_sea.py:1233) — DEFINITELY caused by my @taxman ledger sprint (f44a282). The Brief banner on /gameboard/my-sea/ is now server-driven via the `free_draw_brief_payload` context var, which `my_sea_lock` emits via `log_tax_debit` on the first card of a cycle. This FT bypasses `my_sea_lock` by ORM-creating the MySeaDraw row (`_save_draw_for_user` helper) — no tax-debit emitted, no payload, no banner, selector fails. Fix: explicitly call `log_tax_debit(self.gamer, "free_draw_locked")` after the ORM seed, mirroring what `my_sea_lock` would have done in the real flow. Kept the seed scoped to test 3 only (the only test that asserts the Brief); the other tests using `_save_draw_for_user` (picker phase, saved hand slots, DEL portal, etc.) don't need it.

2. `test_carte_blanche_equip_and_multi_slot_gatekeeper` (test_trinket_carte_blanche.py:82) — selector for `.my-sea-sign-gate-brief` (added in `a133a9c` per polish-9 race fix) fails ONLY in the CI batched run, NOT in isolation (3× local runs pass, including running the full carte test class). The most likely chain: the my_sea FT above fails alphabetically FIRST in the batch, raises NoSuchElement after the 10s wait_for timeout. That can leave the test runner / geckodriver / Firefox in a transient bad state that the next test (carte blanche) inherits. Common signature for this kind of CI-only cascade w. one root cause: fix the upstream test, downstream clears too.

Local sweep: the my_sea fix in isolation passes (12.881s); the full carte class passes (34.456s, 3 tests). Expectation: CI pipeline #343 will clear both errors w. this one-line fix.

If carte still fails on the next CI run after the my_sea fix lands, the next step is to inspect the CI screendump for the carte failure (not synced to local) to see what state the page was actually in.

Code architected by Disco DeDisco <discodedisco@outlook.com>
Git commit message Co-Authored-By:
Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Disco DeDisco
2026-05-26 18:19:11 -04:00
parent c84b3ba9f3
commit 3ad372bc36

View File

@@ -1234,12 +1234,27 @@ class MySeaLockHandTest(FunctionalTest):
"""Post-lock UX: a Look!-formatted Brief banner appears atop the """Post-lock UX: a Look!-formatted Brief banner appears atop the
h2 (standard portaled `.note-banner` w. Gaussian-glass bg, same h2 (standard portaled `.note-banner` w. Gaussian-glass bg, same
styling as my-notes / my-sign default-deck-warning Briefs). The styling as my-notes / my-sign default-deck-warning Briefs). The
next-free-draw timestamp lives in the dedicated `.note-banner__ spend-moment timestamp lives in the dedicated `.note-banner__
timestamp` `<time>` slot (note.js's standard datetime element), timestamp` `<time>` slot (note.js's standard datetime element),
formatted by JS to `D, M j @ g:i A` shape — e.g. "Wed, May 20 @ formatted by JS to `D, M j @ g:i A` shape — e.g. "Wed, May 20 @
11:57 PM". Tagged `.my-sea-locked-banner` so this FT disambiguates 11:57 PM". Tagged `.my-sea-locked-banner` so this FT disambiguates
from any other Briefs that may stack on the page.""" from any other Briefs that may stack on the page.
Sprint 2026-05-26 (@taxman ledger) update — the Brief banner is
now server-driven via the `free_draw_brief_payload` context var,
which surfaces ONLY when a TAX_LEDGER Brief exists for the user.
`my_sea_lock` emits one automatically on the first card of a
cycle; this FT bypasses `my_sea_lock` by ORM-creating the
MySeaDraw row, so it must ALSO seed the matching tax-debit
Brief explicitly (mirrors what `my_sea_lock` would have done)."""
self._save_draw_for_user() self._save_draw_for_user()
# Seed the TAX_LEDGER Brief the server-driven my_sea.html template
# gates on. Without this, `free_draw_brief_payload` is None in
# context + no banner renders. (Real `my_sea_lock` calls log_tax_
# debit on the first-card-of-cycle branch — this FT bypasses that
# path by ORM-creating MySeaDraw, so the seed has to be manual.)
from apps.billboard.tax import log_tax_debit
log_tax_debit(self.gamer, "free_draw_locked")
self.create_pre_authenticated_session(self.email) self.create_pre_authenticated_session(self.email)
self.browser.get(self.live_server_url + "/gameboard/my-sea/") self.browser.get(self.live_server_url + "/gameboard/my-sea/")
brief = self.wait_for( brief = self.wait_for(