phase: 88_mobile_chat_hamburger_boot
All completion criteria verified green. Final state confirmed: phase stays in `todo/` per A4 (owner device gate), task files in `complete/`, no `app/` changes, no commits made (harness commits). ## Phase 88 — final verification pass report **Verified (all 6 tasks already complete):** `touch-action: manipulation` on mobile `#nav-toggle`; `#view-chat.chat-booted` double-rAF sticky handover (CSS gate + app.js boot IIFE); `body.nav-menu-open` marker in `setNavMenu` + ≤640px `visibility: hidden` rule; router boot contract (`wasMounted && !opts.boot` + `boot: true`); new unit module (10 pins) + 4-test real-touch E2E story. **Test / lint / coverage:** - `uv run pytest --cov=app --cov-report=term-missing` → 1741 passed, **99%** on `app/` (>90% ✓) - `tests/e2e/test_mobile_chat_hamburger_boot.py` 4/4, `test_mobile_hamburger_nav.py` 8/8, `test_pinned_composer.py` 4/4, `test_smoke.py` 3/3 — each in isolation, `--no-cov` ✓ - `uv run ruff check .` clean; `uv run pyright` 0 errors ✓ **Completion criteria:** (1) 360px cold-boot touch-action + sticky handover + tap-opens-menu-with-cluster-hidden (E2E 1–2) ✓; (2) boot fires no `bor:view-refresh`, re-show fires exactly one, `/sources.html` regression (E2E 3–4) ✓; (3) full gate green ✓; (4) diff limited to 4 assets + 2 new tests + phase files, 0 changes in `app/` ✓; (5) commit deferred to harness per executor rules ✓; (6) owner device re-verification **pending** (A4 — gates the archive; no Owner report recorded yet). **Deviations (both documented in-tree):** unit pins updated in `test_frontend_router.py`/`test_hamburger_nav.py` (their exact-text pins collided with the mandated new guard/marker text — without them the suite goes red); `boot: true` count pinned at 1 not 2 (codebase has one boot call site, no `history.state` branch — verified against git HEAD). **Next pending phase:** none in `todo/` — pipeline awaits the owner's on-device report (archive, or `?dbg=nav` instrumentation follow-up if the menu is still dead).
This commit is contained in:
@@ -525,7 +525,11 @@ def test_the_binding_toggles_only_the_container() -> None:
|
||||
"""The auth visibility contract is untouched: the binding never
|
||||
assigns ``.hidden`` and never touches the whoami links — hidden
|
||||
links stay hidden inside the menu, exactly as on the inline bar.
|
||||
Only the .is-open container class + aria-expanded move."""
|
||||
Only the .is-open container class + aria-expanded move — plus,
|
||||
since phase 88, the body-level ``nav-menu-open`` marker (task 03:
|
||||
it rides on setNavMenu — the same single choke point — so the
|
||||
marker can never stick while the ≤640px CSS hides the chat
|
||||
cluster behind the open menu). No OTHER class may move."""
|
||||
section = _js_clean(_hamburger_section(_js()))
|
||||
assert ".hidden" not in section, (
|
||||
"the hamburger binding must not hide/reveal any element"
|
||||
@@ -534,8 +538,10 @@ def test_the_binding_toggles_only_the_container() -> None:
|
||||
assert link not in section, (
|
||||
f"the hamburger binding must not touch the {link!r} link"
|
||||
)
|
||||
# The only class the section manipulates is the container's state.
|
||||
# The only classes the section manipulates are the container's
|
||||
# state (is-open) and the phase-88 body marker (nav-menu-open).
|
||||
class_toggles = re.findall(r"classList\.(?:add|remove|toggle)\(\s*\"([^\"]+)\"", section)
|
||||
assert class_toggles == ["is-open"], (
|
||||
f"only the container .is-open class may move (found {class_toggles})"
|
||||
assert class_toggles == ["is-open", "nav-menu-open"], (
|
||||
f"only the container .is-open class + the phase-88 "
|
||||
f"body.nav-menu-open marker may move (found {class_toggles})"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user