Compare commits
2 Commits
2892b51101
...
e28d55ad58
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e28d55ad58 | ||
|
|
b110bb6d01 |
@@ -442,28 +442,7 @@ class GameKitPageTest(FunctionalTest):
|
||||
self.assertGreater(len(visible), 1)
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# Test 11 — next button advances the active card #
|
||||
# ------------------------------------------------------------------ #
|
||||
|
||||
@unittest.skip("fan-nav button obscured by dialog at 1366×900 — fix with tray/room.html styling pass")
|
||||
def test_fan_next_button_advances_card(self):
|
||||
self.browser.get(self.live_server_url + "/gameboard/game-kit/")
|
||||
self.wait_for(
|
||||
lambda: self.browser.find_element(By.CSS_SELECTOR, "#id_gk_decks .gk-deck-card")
|
||||
).click()
|
||||
first_index = self.wait_for(
|
||||
lambda: self.browser.find_element(By.CSS_SELECTOR, ".fan-card--active")
|
||||
).get_attribute("data-index")
|
||||
self.browser.find_element(By.ID, "id_fan_next").click()
|
||||
self.wait_for(
|
||||
lambda: self.assertNotEqual(
|
||||
self.browser.find_element(By.CSS_SELECTOR, ".fan-card--active").get_attribute("data-index"),
|
||||
first_index,
|
||||
)
|
||||
)
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# Test 12 — clicking outside the modal closes it #
|
||||
# Test 11 — clicking outside the modal closes it #
|
||||
# ------------------------------------------------------------------ #
|
||||
|
||||
def test_pressing_escape_closes_fan_modal(self):
|
||||
@@ -477,37 +456,3 @@ class GameKitPageTest(FunctionalTest):
|
||||
dialog.send_keys(Keys.ESCAPE)
|
||||
self.wait_for(lambda: self.assertFalse(dialog.is_displayed()))
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# Test 13 — reopening the modal remembers scroll position #
|
||||
# ------------------------------------------------------------------ #
|
||||
|
||||
@unittest.skip("fan-nav button obscured by dialog at 1366×900 — fix with tray/room.html styling pass")
|
||||
def test_fan_remembers_position_on_reopen(self):
|
||||
self.browser.get(self.live_server_url + "/gameboard/game-kit/")
|
||||
deck_card = self.wait_for(
|
||||
lambda: self.browser.find_element(By.CSS_SELECTOR, "#id_gk_decks .gk-deck-card")
|
||||
)
|
||||
deck_card.click()
|
||||
self.wait_for(lambda: self.browser.find_element(By.CSS_SELECTOR, ".fan-card--active"))
|
||||
# Advance 3 cards
|
||||
for _ in range(3):
|
||||
self.browser.find_element(By.ID, "id_fan_next").click()
|
||||
saved_index = self.wait_for(
|
||||
lambda: self.browser.find_element(By.CSS_SELECTOR, ".fan-card--active").get_attribute("data-index")
|
||||
)
|
||||
# Close via ESC
|
||||
from selenium.webdriver.common.keys import Keys
|
||||
self.browser.find_element(By.ID, "id_tarot_fan_dialog").send_keys(Keys.ESCAPE)
|
||||
self.wait_for(
|
||||
lambda: self.assertFalse(
|
||||
self.browser.find_element(By.ID, "id_tarot_fan_dialog").is_displayed()
|
||||
)
|
||||
)
|
||||
# Reopen and verify position restored
|
||||
deck_card.click()
|
||||
self.wait_for(
|
||||
lambda: self.assertEqual(
|
||||
self.browser.find_element(By.CSS_SELECTOR, ".fan-card--active").get_attribute("data-index"),
|
||||
saved_index,
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from django.conf import settings as django_settings
|
||||
from django.test import tag
|
||||
@@ -17,18 +16,9 @@ from .test_room_role_select import _fill_room_via_orm
|
||||
|
||||
# ── Significator Selection ────────────────────────────────────────────────────
|
||||
#
|
||||
# After all 6 roles are revealed the room enters SIG_SELECT. A 36-card
|
||||
# Significator deck appears at the table centre; gamers pick in seat order
|
||||
# (PC → NC → EC → SC → AC → BC). Selected cards are removed from the shared
|
||||
# pile in real time via WebSocket, exactly as role selection works.
|
||||
#
|
||||
# Deck composition (18 unique cards × 2 — one from levity, one from gravity):
|
||||
# SC / AC (Shepherd / Alchemist) → M/J/Q/K of Swords & Cups (16 cards)
|
||||
# PC / BC (Player / Builder) → M/J/Q/K of Wands & Pentacles (16 cards)
|
||||
# NC / EC (Narrator / Economist) → The Schiz (0) + Chancellor (1) ( 4 cards)
|
||||
#
|
||||
# Levity pile: SC, PC, NC contributions. Gravity pile: AC, BC, EC contributions.
|
||||
# Cards retain the contributor's deck card-back — up to 6 distinct backs active.
|
||||
# After all 6 roles are revealed the room enters SIG_SELECT. Two parallel
|
||||
# 18-card overlays appear (levity: PC/NC/SC; gravity: BC/EC/AC). Each polarity
|
||||
# group picks simultaneously — no sequential turn order.
|
||||
#
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -93,34 +83,7 @@ class SigSelectTest(FunctionalTest):
|
||||
)
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# Test S1 — Significator deck of 36 cards appears at table centre #
|
||||
# ------------------------------------------------------------------ #
|
||||
|
||||
def test_sig_deck_appears_with_36_cards_after_all_roles_revealed(self):
|
||||
founder, _ = User.objects.get_or_create(email="founder@test.io")
|
||||
room = Room.objects.create(name="Sig Deck Test", owner=founder)
|
||||
_fill_room_via_orm(room, [
|
||||
"founder@test.io", "amigo@test.io", "bud@test.io",
|
||||
"pal@test.io", "dude@test.io", "bro@test.io",
|
||||
])
|
||||
_assign_all_roles(room)
|
||||
|
||||
self.create_pre_authenticated_session("founder@test.io")
|
||||
room_url = f"{self.live_server_url}/gameboard/room/{room.id}/gate/"
|
||||
self.browser.get(room_url)
|
||||
|
||||
# Significator deck is visible at the table centre
|
||||
sig_deck = self.wait_for(
|
||||
lambda: self.browser.find_element(By.ID, "id_sig_deck")
|
||||
)
|
||||
self.assertTrue(sig_deck.is_displayed())
|
||||
|
||||
# It contains exactly 36 cards
|
||||
cards = self.browser.find_elements(By.CSS_SELECTOR, "#id_sig_deck .sig-card")
|
||||
self.assertEqual(len(cards), 36)
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# Test S2 — Seats reorder to canonical role sequence at SIG_SELECT #
|
||||
# Test S1 — Seats reorder to canonical role sequence at SIG_SELECT #
|
||||
# ------------------------------------------------------------------ #
|
||||
|
||||
def test_seats_display_in_pc_nc_ec_sc_ac_bc_order_after_reveal(self):
|
||||
@@ -146,88 +109,6 @@ class SigSelectTest(FunctionalTest):
|
||||
roles_in_order = [s.get_attribute("data-role") for s in seats]
|
||||
self.assertEqual(roles_in_order, SIG_SEAT_ORDER)
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# Test S3 — First seat (PC) can select a significator; deck shrinks #
|
||||
# ------------------------------------------------------------------ #
|
||||
|
||||
def test_first_seat_pc_can_select_significator_and_deck_shrinks(self):
|
||||
founder, _ = User.objects.get_or_create(email="founder@test.io")
|
||||
room = Room.objects.create(name="PC Select Test", owner=founder)
|
||||
# Founder is assigned PC (slot 1 → first in canonical order → active)
|
||||
_fill_room_via_orm(room, [
|
||||
"founder@test.io", "amigo@test.io", "bud@test.io",
|
||||
"pal@test.io", "dude@test.io", "bro@test.io",
|
||||
])
|
||||
_assign_all_roles(room, role_order=["PC", "NC", "EC", "SC", "AC", "BC"])
|
||||
|
||||
self.create_pre_authenticated_session("founder@test.io")
|
||||
room_url = f"{self.live_server_url}/gameboard/room/{room.id}/gate/"
|
||||
self.browser.get(room_url)
|
||||
|
||||
# 36-card sig deck is present and the founder's seat is active
|
||||
self.wait_for(
|
||||
lambda: self.browser.find_element(By.CSS_SELECTOR, "#id_sig_deck .sig-card")
|
||||
)
|
||||
self.wait_for(
|
||||
lambda: self.browser.find_element(
|
||||
By.CSS_SELECTOR, ".table-seat.active[data-role='PC']"
|
||||
)
|
||||
)
|
||||
|
||||
# Click the first card in the significator deck to select it
|
||||
first_card = self.browser.find_element(
|
||||
By.CSS_SELECTOR, "#id_sig_deck .sig-card"
|
||||
)
|
||||
first_card.click()
|
||||
self.confirm_guard()
|
||||
|
||||
# Deck now has 35 cards — one pile copy of the selected card removed
|
||||
self.wait_for(
|
||||
lambda: self.assertEqual(
|
||||
len(self.browser.find_elements(By.CSS_SELECTOR, "#id_sig_deck .sig-card")),
|
||||
35,
|
||||
)
|
||||
)
|
||||
|
||||
# TODO: sig card should appear in the tray (tray.placeCard for sig phase)
|
||||
# once sig-select.js is updated to call Tray.placeCard instead of
|
||||
# appending to the removed #id_inv_sig_card inventory element.
|
||||
|
||||
# Active seat advances to NC
|
||||
self.wait_for(
|
||||
lambda: self.browser.find_element(
|
||||
By.CSS_SELECTOR, ".table-seat.active[data-role='NC']"
|
||||
)
|
||||
)
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# Test S4 — Ineligible seat cannot interact with sig deck #
|
||||
# ------------------------------------------------------------------ #
|
||||
|
||||
def test_non_active_seat_cannot_select_significator(self):
|
||||
founder, _ = User.objects.get_or_create(email="founder@test.io")
|
||||
room = Room.objects.create(name="Ineligible Sig Test", owner=founder)
|
||||
# Founder is NC (second in canonical order) — not first
|
||||
_fill_room_via_orm(room, [
|
||||
"founder@test.io", "amigo@test.io", "bud@test.io",
|
||||
"pal@test.io", "dude@test.io", "bro@test.io",
|
||||
])
|
||||
_assign_all_roles(room, role_order=["NC", "PC", "EC", "SC", "AC", "BC"])
|
||||
|
||||
self.create_pre_authenticated_session("founder@test.io")
|
||||
room_url = f"{self.live_server_url}/gameboard/room/{room.id}/gate/"
|
||||
self.browser.get(room_url)
|
||||
|
||||
self.wait_for(lambda: self.browser.find_element(By.ID, "id_sig_deck"))
|
||||
|
||||
# Click a sig card — it must not trigger a selection (deck stays at 36)
|
||||
self.browser.find_element(By.CSS_SELECTOR, "#id_sig_deck .sig-card").click()
|
||||
self.wait_for(
|
||||
lambda: self.assertEqual(
|
||||
len(self.browser.find_elements(By.CSS_SELECTOR, "#id_sig_deck .sig-card")),
|
||||
36,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@tag("channels")
|
||||
@@ -257,61 +138,3 @@ class SigSelectChannelsTest(ChannelsFunctionalTest):
|
||||
))
|
||||
return b
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# Test S5 — Selected sig card disappears for watching gamer (WS) #
|
||||
# ------------------------------------------------------------------ #
|
||||
|
||||
@unittest.skip("sig deck card count wrong in channels context (40 != 36) — grand overhaul pending")
|
||||
def test_selected_sig_card_removed_from_deck_for_other_gamers(self):
|
||||
founder, _ = User.objects.get_or_create(email="founder@test.io")
|
||||
User.objects.get_or_create(email="watcher@test.io")
|
||||
room = Room.objects.create(name="Sig WS Test", owner=founder)
|
||||
_fill_room_via_orm(room, [
|
||||
"founder@test.io", "watcher@test.io", "bud@test.io",
|
||||
"pal@test.io", "dude@test.io", "bro@test.io",
|
||||
])
|
||||
# Founder is PC (active first); watcher is NC (second)
|
||||
_assign_all_roles(room, role_order=["PC", "NC", "EC", "SC", "AC", "BC"])
|
||||
room_url = f"{self.live_server_url}/gameboard/room/{room.id}/gate/"
|
||||
|
||||
# Watcher loads room, sees 36 cards
|
||||
self.create_pre_authenticated_session("watcher@test.io")
|
||||
self.browser.get(room_url)
|
||||
self.wait_for(
|
||||
lambda: self.assertEqual(
|
||||
len(self.browser.find_elements(By.CSS_SELECTOR, "#id_sig_deck .sig-card")),
|
||||
36,
|
||||
)
|
||||
)
|
||||
|
||||
# Founder picks a significator in second browser
|
||||
self.browser2 = self._make_browser2("founder@test.io")
|
||||
try:
|
||||
self.browser2.get(room_url)
|
||||
self.wait_for(lambda: self.browser2.find_element(
|
||||
By.CSS_SELECTOR, ".table-seat.active[data-role='PC']"
|
||||
))
|
||||
self.browser2.find_element(
|
||||
By.CSS_SELECTOR, "#id_sig_deck .sig-card"
|
||||
).click()
|
||||
self.confirm_guard(browser=self.browser2)
|
||||
|
||||
# Watcher's deck shrinks to 35 without a page reload
|
||||
self.wait_for(
|
||||
lambda: self.assertEqual(
|
||||
len(self.browser.find_elements(
|
||||
By.CSS_SELECTOR, "#id_sig_deck .sig-card"
|
||||
)),
|
||||
35,
|
||||
)
|
||||
)
|
||||
|
||||
# Active seat advances to NC in both browsers
|
||||
self.wait_for(lambda: self.browser.find_element(
|
||||
By.CSS_SELECTOR, ".table-seat.active[data-role='NC']"
|
||||
))
|
||||
self.wait_for(lambda: self.browser2.find_element(
|
||||
By.CSS_SELECTOR, ".table-seat.active[data-role='NC']"
|
||||
))
|
||||
finally:
|
||||
self.browser2.quit()
|
||||
|
||||
@@ -129,9 +129,10 @@
|
||||
#id_game_applet_menu,
|
||||
#id_game_kit_menu,
|
||||
#id_wallet_applet_menu,
|
||||
#id_room_menu,
|
||||
#id_billboard_applet_menu {
|
||||
right: calc(#{$sidebar-w} + 1rem);
|
||||
bottom: 6.6rem; // same as portrait, just shifted right of footer sidebar
|
||||
right: 0.5rem;
|
||||
bottom: 6.6rem;
|
||||
top: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
<div id="id_billboard_applets_container">
|
||||
<div id="id_billboard_applet_menu" style="display:none;">
|
||||
<form
|
||||
hx-post="{% url "billboard:toggle_applets" %}"
|
||||
@@ -23,5 +22,6 @@
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div id="id_billboard_applets_container">
|
||||
{% include "apps/applets/_partials/_applets.html" %}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user