An admin area a phone could reach and not navigate

Administration has a nav of its own rather than the chat sidebar, and 1.1.0
gave every `.sidebar` the drawer behaviour -- starts closed, slides in --
without giving that one any of the drawer's furniture. No id for the toggle to
resolve, no toggle, no close, no scrim: it sat at left:-280 with nothing in the
application able to open it. The close button and the scrim are partials now,
used by both, and the test that guards it *finds* sidebars by scanning the
templates rather than working from a list, which is exactly why this one was
missed.

The chat, measured at 390px, spent forty pixels of side padding and a
forty-four pixel avatar column before drawing a word -- close to a quarter of
the screen on margin, so anything that could not wrap had to be reached
sideways. Padding halved and the avatar moved above the turn; a code block
gained about sixty pixels.

Worse in the same row: `.topbar__actions` asked for 317px of a 390px bar,
because the control that used to give in that row is display:none below a
tablet width, so the group went rigid and the title -- flex: 1 -- was squeezed
to exactly zero. And `.btn--icon` sets a width with no `flex: none`, so the row
shrank the button instead of the text: the sidebar toggle measured eighteen
pixels across. The picker gives now, and shows its avatar rather than its name
on a phone.

Also the instrument, which lied twice more: it could not see horizontal
overflow at all, because `.shell` is overflow:hidden and its "is this
contained" test therefore answered yes for everything on the page; and run from
a copy it resolved `STATIC` to a directory that did not exist, rewrote every
asset URL to a dead file:// path and reported the whole application overflowing
by thirty thousand pixels. It resolves from the imported package now and
asserts that what it rewrote to is really there.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-25 19:27:39 +00:00
co-authored by Claude Opus 5
parent 201281d616
commit b7bf7d728b
12 changed files with 327 additions and 48 deletions
+70 -3
View File
@@ -95,9 +95,12 @@ def test_inert_is_never_left_behind_on_a_widened_window():
def test_the_drawer_is_dismissible_without_finding_a_button():
sidebar = (TEMPLATES / "partials/sidebar.html").read_text(encoding="utf-8")
assert 'class="sidebar-scrim"' in sidebar
assert 'data-toggle="#sidebar"' in sidebar
"""The scrim is a partial because there are two sidebars, so the markup is
asserted where it is defined and its *inclusion* is asserted per sidebar by
`test_every_sidebar_carries_the_way_out_and_the_scrim`."""
scrim = (TEMPLATES / "partials/_sidebar_scrim.html").read_text(encoding="utf-8")
assert 'class="sidebar-scrim"' in scrim
assert 'data-toggle="#sidebar"' in scrim
assert ".sidebar-scrim" in APP_CSS
@@ -113,3 +116,67 @@ def test_the_toggle_is_a_real_target(client: TestClient, registered):
tokens = (ROOT / "web/static/css/tokens.css").read_text(encoding="utf-8")
assert "--tap-min: 2.75rem" in tokens
assert "--control-h: var(--tap-min)" in tokens
# --- Any sidebar, not only the one this was written for ----------------------
def _sidebar_templates() -> list[str]:
"""Every template that renders a sidebar of its own, found rather than
listed -- the admin one was missed precisely because it was not on a list."""
return [
str(p.relative_to(TEMPLATES))
for p in TEMPLATES.rglob("*.html")
if '<aside class="sidebar"' in p.read_text(encoding="utf-8")
]
def test_every_sidebar_is_one_the_toggle_can_find():
"""`data-toggle="#sidebar"` resolves by id, and below the phone breakpoint
`.sidebar` is a fixed overlay that starts closed. A sidebar without that id
is one nothing can open: the admin area shipped that way in 1.1.0 and 1.1.1
-- reachable on a phone, and unnavigable the moment you arrived."""
without = [
name
for name in _sidebar_templates()
if '<aside class="sidebar" id="sidebar"' not in (TEMPLATES / name).read_text(
encoding="utf-8"
)
]
assert not without, f"sidebar with no id, so nothing can open it: {without}"
def test_every_sidebar_carries_the_way_out_and_the_scrim():
missing = []
for name in _sidebar_templates():
text = (TEMPLATES / name).read_text(encoding="utf-8")
if "partials/_sidebar_close.html" not in text:
missing.append(f"{name}: no close button")
if "partials/_sidebar_scrim.html" not in text:
missing.append(f"{name}: no scrim")
assert not missing, missing
def test_the_admin_area_can_be_navigated_on_a_phone(client: TestClient, registered):
"""The whole of administration is in that nav and nowhere else."""
page = client.get("/admin/models").text
assert '<aside class="sidebar" id="sidebar"' in page
assert 'data-toggle="#sidebar"' in page
assert "sidebar-scrim" in page
# --- Controls do not shrink below their own size -----------------------------
def test_an_icon_button_keeps_its_size_in_a_tight_row():
"""`.btn--icon` sets a width and, without `flex: none`, a row that runs out
of room shrinks it instead of the text beside it -- the sidebar toggle
measured 18px across on a 390px chat, well under half its target."""
rule = APP_CSS.split(".btn--icon {", 1)[1].split("}", 1)[0]
assert "flex: none" in rule
def test_the_topbar_can_give_somewhere(client: TestClient, registered):
"""`.topbar__where` was the designated shrinker in that row and it is
`display: none` below 64rem, so on a phone the group went rigid and the
title -- which is `flex: 1` -- was squeezed to exactly zero width."""
actions = APP_CSS.split(".topbar__actions {", 1)[1].split("}", 1)[0]
assert "flex: 0 1 auto" in actions
assert "min-width: 0" in actions
assert "min-width" in APP_CSS.split(".topbar__title {", 1)[1].split("}", 1)[0]