From 66abba3d08021b1ff538d6266e4b4e590407bde2 Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Sun, 20 Sep 2026 01:52:01 +0200 Subject: feat(hub): show the node's public key in Node → Overview MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It was only the Node ID row's fallback, so it vanished the moment the node announced itself — and was labelled Node ID when it did show. Own row, copy button, and the profile's instructions no longer name the node dashboard removed on 2026-09-01. `.node-key` wraps: 44 base64 characters with no break opportunity pushed a 412px document to 417px, which unpins every sticky element on the page. The width probe now measures the Overview table with a real key in it. Co-Authored-By: Claude Opus 5 --- .../tests/test_node_page_width_measured.py | 54 ++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'packages/meshbay-hub/tests') diff --git a/packages/meshbay-hub/tests/test_node_page_width_measured.py b/packages/meshbay-hub/tests/test_node_page_width_measured.py index ebf07ab..bd6a231 100644 --- a/packages/meshbay-hub/tests/test_node_page_width_measured.py +++ b/packages/meshbay-hub/tests/test_node_page_width_measured.py @@ -41,6 +41,29 @@ AUDIT_ROWS = [ ] +# A real Ed25519 public key as the node reports it: 32 bytes of base64, 44 +# characters with not one break opportunity among them. Shortening it here +# would measure the fixture instead of the page -- the exact mistake that let +# a folder name and then a translated column head push this page sideways. +NODE_KEY = "kP3vQ8mZ2rT7xN1bY6wL4hJ9cF5dS0aG8eR2uI7oK4M=" + + +def _overview_table(): + rows = [ + ("Version", "0.14.0"), + ("Node ID", "203.0.113.7:0"), + ("Node key", f'{NODE_KEY}' + ''), + ("QUIC port", "0"), + ("Hub", "https://example.invalid"), + ] + body = "".join(f"{k}{v}" for k, v in rows) + return f""" + + {body} +
""" + + def _audit_table(): head = "".join(f"{c}" for c in ("Time", "Event", "User", "IP", "Group", "Detail")) @@ -64,6 +87,10 @@ FRAGMENT = textwrap.dedent(f"""

Node

+
+

Overview

+ {_overview_table()} +

Audit

{_audit_table()} @@ -87,6 +114,7 @@ FRAGMENT = textwrap.dedent(f""" WIDTHS = [320, 360, 412, 768, 1024] SELECTORS = ["#node.node-page", "#settings", "#node .node-table-scroll", "#node .node-table-audit", "#node .node-group", + "#node .node-table-overview", "#node .node-key", "#settings .settings-section"] @@ -172,3 +200,29 @@ def test_the_audit_table_still_scrolls_itself_on_a_phone(measured, width): page = _box(measured, width, "#node.node-page") assert page["offRight"] == 0, ( f"{page['offRight']} px of the Node page is off a {width} px screen") + + +@pytest.mark.parametrize("width", [320, 360, 412]) +def test_the_node_key_does_not_widen_the_page_on_a_phone(measured, width): + """The Overview table has no scroller of its own. + + `.node-table-audit` may overflow because `.node-table-scroll` contains it. + Overview is a bare `.node-table` in a `.node-group`, so a cell that refuses + to wrap sets the column's minimum width and pushes the document itself + wider than the screen -- which detaches every `position: sticky` element on + the page from a viewport the reader can no longer see, the navigation bar + included. `.node-key` carries `word-break: break-all` for that reason; + remove it and this fails. + """ + r = measured[str(width)] + assert r["docScrollW"] <= r["viewport"]["w"], ( + f"the document scrolls to {r['docScrollW']} px on a {width} px screen " + "— the node key is pushing the page wider instead of wrapping") + table = _box(measured, width, "#node .node-table-overview") + card = _box(measured, width, "#node .node-group") + assert table["width"] <= card["width"], ( + f"at {width} px the Overview table is {table['width']} px inside a " + f"{card['width']} px card — the key is driving the column") + key = _box(measured, width, "#node .node-key") + assert key["offRight"] == 0, ( + f"{key['offRight']} px of the node key is off a {width} px screen") -- cgit v1.2.3