feat(ui): shared header — Sign in/Sign out and New Chat on every page; hide the Sources nav link from anonymous users
This commit is contained in:
@@ -10,7 +10,8 @@ Pinned design (PLAN §7.4 note / phase 14):
|
||||
* save points: user message on send, brain message on ``done``;
|
||||
* every ``localStorage`` access wrapped in try/catch (failure-safe);
|
||||
* size budget ~700k chars, oldest dropped first;
|
||||
* ``#new-chat-btn`` in the chat header (chat page only), ≥44px, ghost pill.
|
||||
* ``#new-chat-btn`` in the shared header bar (chat, sources, viewer —
|
||||
phase 19, owner permission 2026-08-23), ≥44px, ghost pill.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -144,24 +145,29 @@ def test_new_chat_clears_key_and_ui() -> None:
|
||||
assert "removeItem(STORAGE_KEY)" in js
|
||||
|
||||
|
||||
def test_new_chat_button_in_chat_header_only() -> None:
|
||||
"""#new-chat-btn lives in the chat header (index.html) as a real
|
||||
type=button with an accessible name — and nowhere else (A10: chat-page
|
||||
only control)."""
|
||||
def test_new_chat_button_in_the_shared_header_bar() -> None:
|
||||
"""#new-chat-btn is a real type=button with an accessible name in the
|
||||
chat header (index.html). Phase 19 (owner permission 2026-08-23): it
|
||||
is part of the SHARED bar — it also appears in sources.html and the
|
||||
document viewer, where it means "go to the chat, fresh" (the
|
||||
clear-storage + navigate binding is pinned in test_shared_header.py)."""
|
||||
for html in (INDEX_HTML, SOURCES_HTML, DOCUMENT_HTML):
|
||||
text = html.read_text(encoding="utf-8")
|
||||
btn = re.search(r'<button[^>]*id="new-chat-btn"[^>]*>', text)
|
||||
assert btn, f"{html.name} must contain #new-chat-btn"
|
||||
tag = btn.group(0)
|
||||
assert 'type="button"' in tag
|
||||
assert 'aria-label="New chat"' in tag
|
||||
# Chat page specifics: the button sits after the nav, inside the header.
|
||||
html = _index()
|
||||
btn = re.search(r'<button[^>]*id="new-chat-btn"[^>]*>', html)
|
||||
assert btn, "index.html must contain #new-chat-btn"
|
||||
tag = btn.group(0)
|
||||
assert 'type="button"' in tag
|
||||
assert 'aria-label="New chat"' in tag
|
||||
nav_idx = html.find('<nav class="app-nav"')
|
||||
assert nav_idx != -1 and btn.start() > nav_idx, (
|
||||
"the button belongs after the nav, inside .header-inner"
|
||||
)
|
||||
main_idx = html.find('main id="main"')
|
||||
assert main_idx != -1 and btn.start() < main_idx, "the button belongs in the header"
|
||||
assert 'id="new-chat-btn"' not in SOURCES_HTML.read_text(encoding="utf-8")
|
||||
assert 'id="new-chat-btn"' not in DOCUMENT_HTML.read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def test_new_chat_button_style_contract() -> None:
|
||||
|
||||
Reference in New Issue
Block a user