Files
hermes-webui/tests/test_issue3597_update_banner_position.py
nesquena-hermesandrodboev 1bad85feb4 Release v0.51.258 — Release HZ (stage-r6) (#3611)
## Release v0.51.258 — Release HZ (stage-r6)

Fresh-arrival low-risk pair (both @rodboev, landed in the last sweep window).

### Fixed
| Issue | Fix |
|-------|-----|
| #3597 | The "update available" banner now shows from **any panel** (Settings → System "Check now", etc.), not just the Chat view — it was positioned inside the chat surface so it only rendered there. |
| #3592 | Under Simplified Tool Calling, an assistant turn with **thinking but no tool calls** now renders that thinking inline on settlement instead of burying it in an empty collapsed activity group. |

### Review fix absorbed (Codex)
#3592's inline-render `continue` skipped the activity-group creation that carried the turn's `data-turn-duration`, but the footer still suppressed the "Done in …" duration for any `assistantThinking` turn → thinking-only turns silently lost their duration display. Fixed: footer duration is now suppressed **only** for turns that actually build an activity group (`toolCallAssistantIdxs.has(mi)`), so thinking-only inline turns keep "Done in …". + regression test.

### Gate
- Full pytest suite: **7631 passed, 0 failed**
- ESLint: CLEAN · browser-smoke: CLEAN
- Codex (regression): SHIP-ONLY-WITH-FIXES (duration-drop) → fixed → **SAFE TO SHIP**

### Sweep note
#3603 + #3604 (sidebar CLI-session classification, same author/area) were **not** included — they assert contradictory models for a sidecar-less `source='cli'` recovery row; flagged on both PRs for the author to reconcile.

Co-authored-by: rodboev <rodboev@users.noreply.github.com>
2026-06-04 14:28:00 -07:00

30 lines
1.1 KiB
Python

"""Verify #updateBanner lives outside #mainChat so it is visible from any panel."""
import pathlib
INDEX = pathlib.Path(__file__).resolve().parent.parent / "static" / "index.html"
def test_update_banner_outside_main_chat():
src = INDEX.read_text(encoding="utf-8")
banner_pos = src.find('id="updateBanner"')
main_chat_pos = src.find('id="mainChat"')
assert banner_pos != -1, "#updateBanner not found in index.html"
assert main_chat_pos != -1, "#mainChat not found in index.html"
assert banner_pos < main_chat_pos, (
"#updateBanner must appear before #mainChat in the DOM "
"so it is not hidden when non-Chat panels are active"
)
def test_update_banner_inside_main_element():
src = INDEX.read_text(encoding="utf-8")
main_pos = src.find('<main class="main">')
main_end = src.find('</main>')
banner_pos = src.find('id="updateBanner"')
assert main_pos != -1, "<main class='main'> not found"
assert main_end != -1, "</main> not found"
assert main_pos < banner_pos < main_end, (
"#updateBanner must be inside <main class='main'>, "
"not before it or after the closing </main>"
)