note palette: swatch previews body palette, NVM reverts, OK saves sitewide; note_set_palette also saves user.palette — TDD
- note-page.js: body class swap on swatch click; 10s auto-revert timer; NVM reverts; .note-item--active persists border/glow while modal open; .previewing on swatch - billboard/views.py: note_set_palette also saves user.palette via _unlocked_palettes_for_user - _note.scss: .note-swatch-body gradient (palette vars cascade from parent palette-* class); .previewing state; .note-item--active; note-palette-modal tooltip glass; note-palette-confirm floats below modal (position:absolute, out of flow) - my_notes.html: note-item__body wrapper; image-box right; swatch row OK buttons removed - FTs: T2a URL fix (/recognition → /my-notes); T2b split into preview+persist & NVM tests; NoteSetPaletteViewTest.test_also_saves_user_palette IT 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:
@@ -156,7 +156,7 @@ class StargazerNoteFromDashboardTest(FunctionalTest):
|
||||
# FYI navigates to Note page
|
||||
fyi.click()
|
||||
self.wait_for(
|
||||
lambda: self.assertRegex(self.browser.current_url, r"/billboard/recognition")
|
||||
lambda: self.assertRegex(self.browser.current_url, r"/billboard/my-notes")
|
||||
)
|
||||
|
||||
# Note page: one Stargazer item
|
||||
@@ -172,62 +172,106 @@ class StargazerNoteFromDashboardTest(FunctionalTest):
|
||||
|
||||
# ── T2b ──────────────────────────────────────────────────────────────────
|
||||
|
||||
def test_note_page_palette_modal_flow(self):
|
||||
"""Note page palette modal: image-box opens modal, swatch preview,
|
||||
body-click restores modal, OK raises confirm submenu, confirm sets palette."""
|
||||
Note.objects.create(
|
||||
user=self.gamer, slug="stargazer", earned_at=timezone.now(),
|
||||
)
|
||||
self.create_pre_authenticated_session("stargazer@test.io")
|
||||
def _open_modal_and_click_bardo(self):
|
||||
"""Helper: navigate to /billboard/my-notes/, open modal, click bardo swatch body.
|
||||
Returns (modal, confirm_menu) after the confirm bar is visible."""
|
||||
self.browser.get(self.live_server_url + "/billboard/my-notes/")
|
||||
|
||||
image_box = self.wait_for(
|
||||
lambda: self.browser.find_element(By.CSS_SELECTOR, ".note-item__image-box")
|
||||
)
|
||||
|
||||
# Clicking ? opens palette modal
|
||||
image_box.click()
|
||||
modal = self.wait_for(
|
||||
lambda: self.browser.find_element(By.CSS_SELECTOR, ".note-palette-modal")
|
||||
)
|
||||
modal.find_element(By.CSS_SELECTOR, ".palette-bardo")
|
||||
modal.find_element(By.CSS_SELECTOR, ".palette-sheol")
|
||||
|
||||
# Clicking a swatch body previews the palette and dismisses the modal
|
||||
bardo_body = modal.find_element(By.CSS_SELECTOR, ".palette-bardo .note-swatch-body")
|
||||
self.browser.execute_script(
|
||||
"arguments[0].dispatchEvent(new MouseEvent('click', {bubbles: true}))",
|
||||
bardo_body,
|
||||
)
|
||||
self.wait_for(lambda: self.assertFalse(
|
||||
self.browser.find_elements(By.CSS_SELECTOR, ".note-palette-modal")
|
||||
))
|
||||
|
||||
# Clicking elsewhere ends preview and restores the modal
|
||||
self.browser.find_element(By.TAG_NAME, "body").click()
|
||||
modal = self.wait_for(
|
||||
lambda: self.browser.find_element(By.CSS_SELECTOR, ".note-palette-modal")
|
||||
)
|
||||
|
||||
# Clicking OK on the swatch raises a confirmation submenu
|
||||
ok_btn = modal.find_element(By.CSS_SELECTOR, ".palette-bardo .btn.btn-confirm")
|
||||
ok_btn.click()
|
||||
confirm_menu = self.wait_for(
|
||||
lambda: self.browser.find_element(By.CSS_SELECTOR, ".note-palette-confirm")
|
||||
)
|
||||
return modal, confirm_menu
|
||||
|
||||
# Confirming sets palette, closes modal, replaces image-box with palette swatch
|
||||
confirm_menu.find_element(By.CSS_SELECTOR, ".btn.btn-confirm").click()
|
||||
def test_note_page_swatch_previews_palette_sitewide_and_ok_persists(self):
|
||||
"""Clicking a swatch previews that palette on the whole body.
|
||||
OK commits it — Note.palette and user.palette both saved — so it
|
||||
survives navigation to a new page."""
|
||||
Note.objects.create(
|
||||
user=self.gamer, slug="stargazer", earned_at=timezone.now(),
|
||||
)
|
||||
self.create_pre_authenticated_session("stargazer@test.io")
|
||||
|
||||
modal, confirm = self._open_modal_and_click_bardo()
|
||||
|
||||
# Swatch click previews bardo on the whole body
|
||||
self.wait_for(
|
||||
lambda: self.assertIn(
|
||||
"palette-bardo",
|
||||
self.browser.find_element(By.TAG_NAME, "body").get_attribute("class"),
|
||||
)
|
||||
)
|
||||
# Modal still open
|
||||
self.assertTrue(self.browser.find_elements(By.CSS_SELECTOR, ".note-palette-modal"))
|
||||
|
||||
# OK → modal closes, ? box replaced by bardo swatch
|
||||
confirm.find_element(By.CSS_SELECTOR, ".btn.btn-confirm").click()
|
||||
self.wait_for(lambda: self.assertFalse(
|
||||
self.browser.find_elements(By.CSS_SELECTOR, ".note-palette-modal")
|
||||
))
|
||||
item = self.browser.find_element(By.CSS_SELECTOR, ".note-item")
|
||||
self.assertTrue(
|
||||
item.find_elements(By.CSS_SELECTOR, ".note-item__palette.palette-bardo")
|
||||
self.assertTrue(item.find_elements(By.CSS_SELECTOR, ".note-item__palette.palette-bardo"))
|
||||
self.assertFalse(item.find_elements(By.CSS_SELECTOR, ".note-item__image-box"))
|
||||
|
||||
# Navigate away — palette persists (user.palette was saved)
|
||||
self.browser.get(self.live_server_url)
|
||||
self.wait_for(
|
||||
lambda: self.assertIn(
|
||||
"palette-bardo",
|
||||
self.browser.find_element(By.TAG_NAME, "body").get_attribute("class"),
|
||||
)
|
||||
)
|
||||
self.assertFalse(
|
||||
item.find_elements(By.CSS_SELECTOR, ".note-item__image-box")
|
||||
|
||||
def test_note_swatch_nvm_reverts_body_palette(self):
|
||||
"""NVM in the confirm bar reverts the sitewide body palette back to
|
||||
what it was before the swatch was clicked."""
|
||||
Note.objects.create(
|
||||
user=self.gamer, slug="stargazer", earned_at=timezone.now(),
|
||||
)
|
||||
self.create_pre_authenticated_session("stargazer@test.io")
|
||||
|
||||
# Record the original palette before opening the modal
|
||||
self.browser.get(self.live_server_url + "/billboard/my-notes/")
|
||||
original_classes = self.browser.find_element(
|
||||
By.TAG_NAME, "body"
|
||||
).get_attribute("class")
|
||||
original_palette = next(
|
||||
(c for c in original_classes.split() if c.startswith("palette-")), None
|
||||
)
|
||||
|
||||
modal, confirm = self._open_modal_and_click_bardo()
|
||||
|
||||
# Bardo is previewed
|
||||
self.wait_for(
|
||||
lambda: self.assertIn(
|
||||
"palette-bardo",
|
||||
self.browser.find_element(By.TAG_NAME, "body").get_attribute("class"),
|
||||
)
|
||||
)
|
||||
|
||||
# NVM reverts
|
||||
confirm.find_element(By.CSS_SELECTOR, ".btn.btn-cancel").click()
|
||||
self.wait_for(
|
||||
lambda: self.assertNotIn(
|
||||
"palette-bardo",
|
||||
self.browser.find_element(By.TAG_NAME, "body").get_attribute("class"),
|
||||
)
|
||||
)
|
||||
if original_palette:
|
||||
self.assertIn(
|
||||
original_palette,
|
||||
self.browser.find_element(By.TAG_NAME, "body").get_attribute("class"),
|
||||
)
|
||||
|
||||
# ── T2c ──────────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
Reference in New Issue
Block a user