feat(ui): rename nav items — "Sources" becomes "RAG", "Git sources" becomes "Sources"
Owner request (2026-08-28): the two admin-only nav items read like the same thing, so they are relabeled — the document-catalog link (#nav-sources, /sources.html) becomes "RAG" and the source-manager link (#nav-git-sources, /git-sources.html) becomes "Sources". Phase 48 (48_nav_rename_sources), label-only per the locked decision: - all six pages (index, sources, git-sources, tuning, document, login): the two <a> texts swap; ids, hrefs, hidden defaults, is-active / aria-current placement, and nav order (Chat, RAG, Sources, Tuning) are byte-unchanged otherwise. - header.js: comment/docstring label mentions only — the reveal-by-id logic is untouched (ship-hidden/reveal contract intact). - test_git_sources_admin.py / test_mobile_hamburger_nav.py: the two suites that asserted the old label text are updated; comment-only label fixes in test_shared_header.py / test_nav_consistency.py. - tests/e2e/test_nav_rename_sources.py: the story E2E (green in isolation) — renamed labels + unchanged hrefs/order/markers on all six pages, click navigation with the active marker, the anonymous ship-hidden contract, and regression guards for the untouched controls (#sync-label "Sync sources", viewer #doc-back "Sources"). - All eight surrounding header/nav suites stay green in isolation; unit+integration green, app/ coverage 99% (frontend-only change), ruff + pyright clean. Note: per this phase file-level staging, the six page files and header.js also carry the same-day in-flight owner rework that was already in the working tree when phase 48 ran (mobile sign-in dropdown copy, sync button ship-hidden on the Sources page); the label rename itself is the two-text swap on each page.
This commit is contained in:
@@ -19,19 +19,22 @@ sources, document viewer, global tuning, login): one shared markup block
|
||||
Per role, the VISIBLE inventory:
|
||||
|
||||
* admin: brand + nav [Chat, #nav-sources, #nav-git-sources, #nav-tuning]
|
||||
(four links, that order — the Git sources link joined in phase 35,
|
||||
owner permission 2026-08-26) + #sync-btn + #new-chat-btn +
|
||||
#sign-out-btn (with #sign-in-link hidden) — on all five pages, same
|
||||
id+class inventory, same DOM order. The #steering-toggle was removed
|
||||
from the navbar at owner request (2026-08-28); note management lives
|
||||
on /tuning.html;
|
||||
(four links, that order — the "Sources" link joined in phase 35 as
|
||||
"Git sources", owner permission 2026-08-26) + #sign-out-btn (with
|
||||
#sign-in-link
|
||||
hidden) — on all five pages, same id+class inventory, same DOM order.
|
||||
The #sync-btn (Sources page only) and the #new-chat-btn (chat page
|
||||
only) left the shared bar at owner request (2026-08-28 — they are
|
||||
page-specific now, so the per-page visible inventory differs for
|
||||
exactly those two); the #steering-toggle was removed from the navbar
|
||||
the same day; note management lives on /tuning.html;
|
||||
* anonymous: brand + nav [Chat] (#nav-sources / #nav-git-sources /
|
||||
#nav-tuning hidden — locked A10 UI revision) + #new-chat-btn +
|
||||
#sign-in-link (with #sync-btn hidden, #sign-out-btn hidden) on all
|
||||
five pages — and the steering toggle (removed at owner request,
|
||||
2026-08-28) + panel are ABSENT from the DOM (the panel via the phase
|
||||
16 "absent, not hidden" treatment, carried into phase 34 task 01;
|
||||
test_admin_auth pins it).
|
||||
#nav-tuning hidden — locked A10 UI revision) + #sign-in-link (with
|
||||
#sign-out-btn hidden; the Sources page's #sync-btn stays ship-hidden)
|
||||
on all five pages — and the steering toggle (removed at owner
|
||||
request, 2026-08-28) + panel are ABSENT from the DOM (the panel via
|
||||
the phase 16 "absent, not hidden" treatment, carried into phase 34
|
||||
task 01; test_admin_auth pins it).
|
||||
|
||||
Normalization for the inventory comparison: the current-page ``is-active``
|
||||
nav marker and the sign-in ``?next=`` value legitimately differ per page,
|
||||
@@ -47,9 +50,10 @@ Steering off-chat: on /tuning.html (admin, zero notes) the navbar
|
||||
carries no steering toggle (removed at owner request, 2026-08-28) — the
|
||||
header #steering-panel section still ships hidden and the Tuning
|
||||
page's own note list shows the empty state — no chat needed. Sync is
|
||||
present, not triggered: #sync-btn is visible on /tuning.html but is
|
||||
never clicked here (a real sync clones real repos — the full state
|
||||
machine is test_sync_button.py's job).
|
||||
present, not triggered: #sync-btn is visible on /sources.html (its
|
||||
home since the owner rework 2026-08-28) but is never clicked here (a
|
||||
real sync clones real repos — the full state machine is
|
||||
test_sync_button.py's job).
|
||||
|
||||
Determinism note: every assertion is settled-state — each page visit
|
||||
first waits for the whoami toggle to land (exactly one of Sign in /
|
||||
@@ -65,7 +69,7 @@ Test → story mapping (Playwright Mapping Rule):
|
||||
3. ``test_viewer_row1_height_matches_chat_and_titlebar_present``
|
||||
4. ``test_viewer_back_link_honors_back_param``
|
||||
5. ``test_steering_surface_off_chat_on_tuning_page``
|
||||
6. ``test_sync_button_present_on_tuning_page_without_triggering``
|
||||
6. ``test_sync_button_present_on_sources_page_without_triggering``
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -177,7 +181,11 @@ def _header_inventory(page: Page) -> list[str]:
|
||||
``page`` is showing (normalized — see _INVENTORY_JS)."""
|
||||
inv = page.evaluate(_INVENTORY_JS)
|
||||
assert inv is not None, "no `header .header-inner` on this page"
|
||||
assert len(inv) >= 8, f"header control inventory unexpectedly short: {inv}"
|
||||
# Shared bar: brand + the four nav links + Sign in + Sign out = 7
|
||||
# (the #sync-btn / #new-chat-btn selectors keep matching nothing —
|
||||
# they left the bar with the owner rework 2026-08-28; the steering
|
||||
# toggle was removed the same day).
|
||||
assert len(inv) >= 7, f"header control inventory unexpectedly short: {inv}"
|
||||
return inv
|
||||
|
||||
|
||||
@@ -220,8 +228,9 @@ def _visit(page: Page, app_url: str, name: str, url: str, admin: bool) -> list[s
|
||||
expect(page.locator(".app-nav a[href='/']")).to_be_visible() # Chat
|
||||
if admin:
|
||||
expect(page.locator("#nav-sources")).to_be_visible()
|
||||
# Phase 35: the fourth admin-only nav link (Git sources) is
|
||||
# revealed on every page, between Sources and Tuning.
|
||||
# Phase 35: the fourth admin-only nav link (now "Sources",
|
||||
# shipped as "Git sources") is revealed on every page, between
|
||||
# RAG and Tuning.
|
||||
expect(page.locator("#nav-git-sources")).to_be_visible()
|
||||
expect(page.locator("#nav-tuning")).to_be_visible()
|
||||
# The steering toggle was removed from the navbar at owner
|
||||
@@ -229,7 +238,15 @@ def _visit(page: Page, app_url: str, name: str, url: str, admin: bool) -> list[s
|
||||
assert page.locator("#steering-toggle").count() == 0, (
|
||||
f"{name}: the steering toggle was removed from the navbar"
|
||||
)
|
||||
expect(page.locator("#sync-btn")).to_be_visible()
|
||||
# The Sync button is a page-specific control (Sources page only
|
||||
# — owner rework 2026-08-28): visible on sources, absent from
|
||||
# the shared bar everywhere else.
|
||||
if name == "sources":
|
||||
expect(page.locator("#sync-btn")).to_be_visible()
|
||||
else:
|
||||
assert page.locator("#sync-btn").count() == 0, (
|
||||
f"{name}: #sync-btn left the shared bar (Sources page only)"
|
||||
)
|
||||
expect(page.locator("#sign-out-btn")).to_be_visible()
|
||||
expect(page.locator("#sign-in-link")).to_be_hidden()
|
||||
else:
|
||||
@@ -252,7 +269,14 @@ def _visit(page: Page, app_url: str, name: str, url: str, admin: bool) -> list[s
|
||||
assert page.locator("#steering-panel").count() == 0, (
|
||||
f"{name}: the steering panel must be absent for anonymous"
|
||||
)
|
||||
expect(page.locator("#new-chat-btn")).to_be_visible()
|
||||
# The New chat button is chat-page only (moved from the shared bar
|
||||
# to index.html's .chat-shell at owner request, 2026-08-28).
|
||||
if name == "chat":
|
||||
expect(page.locator("#new-chat-btn")).to_be_visible()
|
||||
else:
|
||||
assert page.locator("#new-chat-btn").count() == 0, (
|
||||
f"{name}: #new-chat-btn left the shared bar (chat page only)"
|
||||
)
|
||||
|
||||
_assert_landmarks(page, name)
|
||||
return _header_inventory(page)
|
||||
@@ -302,10 +326,12 @@ def _admin_login_page_inventory(page: Page, app_url: str) -> list[str]:
|
||||
assert page.locator("#steering-toggle").count() == 0, (
|
||||
"login: the steering toggle was removed from the navbar"
|
||||
)
|
||||
expect(page.locator("#sync-btn")).to_be_visible()
|
||||
# Page-specific controls are NOT on the auth page (owner rework
|
||||
# 2026-08-28: sync → Sources page, new chat → chat page).
|
||||
assert page.locator("#sync-btn").count() == 0
|
||||
assert page.locator("#new-chat-btn").count() == 0
|
||||
expect(page.locator("#sign-out-btn")).to_be_visible()
|
||||
expect(page.locator("#sign-in-link")).to_be_hidden()
|
||||
expect(page.locator("#new-chat-btn")).to_be_visible()
|
||||
_assert_landmarks(page, "login")
|
||||
return _header_inventory(page)
|
||||
finally:
|
||||
@@ -482,14 +508,16 @@ def test_steering_surface_off_chat_on_tuning_page(
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def test_sync_button_present_on_tuning_page_without_triggering(
|
||||
def test_sync_button_present_on_sources_page_without_triggering(
|
||||
page: Page, app_url: str, mock_llm: int, db_ready: None
|
||||
) -> None:
|
||||
page.set_viewport_size({"width": 1280, "height": 800})
|
||||
_seed_db(mock_llm)
|
||||
|
||||
login(page, app_url, next=TUNING_URL)
|
||||
expect(page).to_have_url(app_url + TUNING_URL, timeout=30_000)
|
||||
# The button's home is the Sources page (owner rework 2026-08-28 —
|
||||
# it left the shared navbar).
|
||||
login(page, app_url, next=SOURCES_URL)
|
||||
expect(page).to_have_url(app_url + SOURCES_URL, timeout=30_000)
|
||||
expect(page.locator("#sign-out-btn")).to_be_visible(timeout=15_000)
|
||||
|
||||
btn = page.locator("#sync-btn")
|
||||
|
||||
Reference in New Issue
Block a user