Files
brain-of-reese/.agents/phases/complete/62_ui_customization/05_e2e_customization.md
T
ducoterra dbf2af26c6 refactor(agents): migrate .agent/ planning tree to .agents/
Standardize on the .agents/ directory (shared with project skills):
phases/, user_stories/, reports/, screenshots/, validate.sh, and
phase-sessions/ + pipeline.log all move to .agents/ (git mv preserves
history; runtime artifacts move alongside).

Updates every reference in AGENTS.md, README.md, .gitignore, app
docstrings, and test story headers. Historical KB content in data/
and the runtime pipeline.log transcript are left untouched.
2026-09-05 10:57:07 -04:00

4.3 KiB

Task 05 — Dedicated E2E + regression pass + atomic commit

Phase: 62_ui_customization · Source: TODO.md:3 — "Allow UI customization. This is brain of reese, but I want anyone to be able to deploy it with their name…" Story: n/a (TODO-derived)

Objective

One dedicated Playwright suite proves the whole contract end-to-end — an instance booted with all three customization vars shows the custom look, the default shared server is BYTE-IDENTICAL to today, and a malformed BOR_THEME refuses to boot — then one atomic commit and the phase is done.

Work

  1. tests/e2e/test_ui_customization.py (NEW — one story, one file, run in isolation, DB up). Boots a second app instance exactly the way test_configurable_brand.py's testy_server does (same env block, same DB, mock-LLM base URL, admin auth, static dir, mock-calibrated threshold) with THREE changes: port APP_PORT + 2 (the brand suite owns APP_PORT + 1 — do not collide), and the env overrides BOR_INPUT_PLACEHOLDER="Ask the archive…", BOR_FOOTER_TEXT="Custom footer line", BOR_THEME="indigo.css". Test → contract mapping:
    1. test_config_serves_the_overrides — the instance's GET /api/config returns the three overridden values alongside the six-key set (the name stays the DEFAULT — this suite does not re-test BOR_APP_NAME; that is the phase-39 suite's job).
    2. test_chat_page_shows_custom_placeholder_footer_theme (instance) — on the chat page: #message-input placeholder === Ask the archive…; the first .footer-text textContent === Custom footer line; a link#theme-override[rel="stylesheet"][href="/assets/themes/indigo.css"] exists in the <head>; getComputedStyle(document.documentElement).getPropertyValue("--brand").trim() === #818cf8 (the indigo value — custom properties return the specified token, so the string compare is stable; the built-in is #f43f5e).
    3. test_footer_text_applies_on_other_pages (instance) — on a second page (e.g. /login.html): the .footer-text textContent === Custom footer line (multi-page proof, no composer on that page — the placeholder application no-ops without error).
    4. test_default_server_is_byte_identical (shared conftest server) — placeholder === Ask me anything…; footer === Powered by self-hosted models; NO #theme-override link; computed --brand === #f43f5e (the phase-39/61 no-op contract).
    5. test_malformed_theme_refuses_startup — boot a short-lived uvicorn subprocess with BOR_THEME="../evil.css" (any port): the process exits non-zero within the timeout (or never starts listening) and its stderr names the value — the phase-56 fail-loud style, proven end-to-end, not just via the validator unit test.
    • Determinism: settled-state assertions throughout; Playwright expect retries ride out the brand.js fetch (the same pattern the brand suite documents in its module docstring).
  2. Regression E2E pass (each in isolation, DB up): test_configurable_brand.py (its key-set assertions were updated in task 01), test_stale_ui_copy.py (phase 61's copy contract is this phase's baseline), test_smoke.py, test_dark_tech_theme.py (the built-in palette is untouched when unset).
  3. One atomic commit (.agents/ untracked — owner instruction, commit 281f355):
    git add app/ frontend/ tests/ .env.example README.md Containerfile && git commit --no-gpg-sign -m "feat(web): customizable placeholder, footer text, and color theme via BOR_* env vars"
    
    Commit body: one line — the three env vars + the indigo example theme + the docs/theme-guide pointers.

Testing & Quality

  • uv run pytest green (unit + integration); coverage TOTAL >90% (validate.sh gate).
  • uv run pytest tests/e2e/test_ui_customization.py -v --no-cov green in isolation.
  • uv run ruff check . && uv run pyright clean.

Completion Criteria

  • tests/e2e/test_ui_customization.py exists (5 mapped tests) and is green in isolation (DB up).
  • The four regression E2E suites are green in isolation.
  • Full suite green, coverage >90%, lint + types clean.
  • Exactly one new commit on main, staged paths app/ frontend/ tests/ .env.example README.md Containerfile, --no-gpg-sign.
  • Phase dir moved to .agents/phases/complete/62_ui_customization/ (.agents/ stays untracked).