aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/tests/test_layout_measured.py
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-hub/tests/test_layout_measured.py')
-rw-r--r--packages/meshbay-hub/tests/test_layout_measured.py119
1 files changed, 118 insertions, 1 deletions
diff --git a/packages/meshbay-hub/tests/test_layout_measured.py b/packages/meshbay-hub/tests/test_layout_measured.py
index 91f1ed0..a71b6b9 100644
--- a/packages/meshbay-hub/tests/test_layout_measured.py
+++ b/packages/meshbay-hub/tests/test_layout_measured.py
@@ -54,7 +54,7 @@ NAV = textwrap.dedent("""
<div class="transfer-item">
<div class="transfer-line">
<span class="transfer-kind">&#8595;</span>
- <span class="transfer-name">S03E01. Salt and Sea, Fire and Blood.mp4</span>
+ <span class="transfer-name">Some Saga S03E01 - A Long Enough Title.mp4</span>
<button class="transfer-cancel">&#10005;</button>
</div>
<div class="dl-progress"><div class="dl-fill" style="width:42%"></div></div>
@@ -144,3 +144,120 @@ def test_the_page_does_not_scroll_sideways(measured, width):
r = measured[str(width)]
assert r["docScrollW"] <= r["viewport"]["w"], (
f"the document scrolls to {r['docScrollW']} px on a {width} px screen")
+
+
+# ── The grouped panel (§8.2) ────────────────────────────────────────────────
+#
+# The panel gained groups, a header summary and a waiting row. Every one of
+# those can push something off a 320 px screen, and none of it can be seen by
+# reading the stylesheet: what decides where the panel lands is the button it
+# hangs from, which is not at the right edge. That is the defect this file was
+# written for, and it comes back with any change to the header's width.
+
+GROUPED = textwrap.dedent("""
+ <nav class="nav">
+ <div class="nav-left">
+ <button class="nav-hamburger">&#9776;</button>
+ <a class="nav-brand" href="#/">MeshBay</a>
+ </div>
+ <div class="nav-right">
+ <div class="transfer-wrap">
+ <button class="nav-notif transfer-btn">&#8595;</button>
+ <div class="transfer-panel">
+ <div class="transfer-head">
+ <span class="transfer-head-title">Transfers</span>
+ <span class="transfer-head-summary">2 running &middot; 3 waiting</span>
+ <button class="btn-secondary">Clear finished</button>
+ </div>
+ <div class="transfer-group">
+ <div class="transfer-group-head">Running</div>
+ <div class="transfer-item transfer-running">
+ <div class="transfer-line">
+ <span class="transfer-kind">&#8595;</span>
+ <span class="transfer-name">Some Saga S03E01 - A Long Enough Title.mp4</span>
+ <button class="transfer-cancel">&#10005;</button>
+ </div>
+ <div class="dl-progress"><div class="dl-fill" style="width:42%"></div></div>
+ <div class="transfer-meta"><span>210 MB / 493 MB</span><span>3.1 MB/s &middot; 4 min left</span></div>
+ </div>
+ </div>
+ <div class="transfer-group">
+ <div class="transfer-group-head">Waiting</div>
+ <div class="transfer-item transfer-queued">
+ <div class="transfer-line">
+ <span class="transfer-kind">&#8595;</span>
+ <span class="transfer-name">Another File With A Long Name.mkv</span>
+ <button class="transfer-cancel">&#10005;</button>
+ </div>
+ <div class="dl-progress dl-waiting"></div>
+ <div class="transfer-meta"><span>Waiting &mdash; your slots are busy</span><span>1.2 GB</span></div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <a class="nav-notif" href="#/">&#128276;</a>
+ <div class="user-menu"><button class="nav-btn">someone</button></div>
+ </div>
+ </nav>
+""")
+
+GROUPED_SELECTORS = [".transfer-panel", ".transfer-head", ".transfer-head-summary",
+ ".transfer-group-head", ".transfer-name",
+ ".transfer-item.transfer-queued .dl-progress"]
+
+
+@pytest.fixture(scope="module")
+def grouped(tmp_path_factory):
+ fragment = tmp_path_factory.mktemp("grouped") / "fragment.html"
+ fragment.write_text(GROUPED)
+ proc = subprocess.run(
+ ["python3", str(HARNESS), ",".join(str(w) for w in WIDTHS),
+ str(fragment), *GROUPED_SELECTORS],
+ capture_output=True, text=True, timeout=180)
+ assert proc.returncode == 0, f"probe failed: {proc.stdout}{proc.stderr}"
+ out = json.loads(proc.stdout)
+ assert "error" not in out, f"no measurement: {out}"
+ return out
+
+
+def test_the_grouped_panel_stays_on_a_phone_screen(grouped):
+ for width in WIDTHS:
+ box = grouped[str(width)]["boxes"][".transfer-panel"]
+ assert box["offLeft"] == 0, (
+ f"at {width} px the panel hangs {box['offLeft']} px off the left — "
+ "which is where the file names are")
+ assert box["offRight"] == 0, (
+ f"at {width} px the panel hangs {box['offRight']} px off the right")
+
+
+def test_the_file_name_is_on_screen_in_every_group(grouped):
+ for width in WIDTHS:
+ box = grouped[str(width)]["boxes"][".transfer-name"]
+ assert box["offLeft"] == 0 and box["offRight"] == 0, (
+ f"at {width} px a file name is cut off: {box}")
+ assert box["width"] > 40, "the name column collapsed to nothing"
+
+
+def test_the_header_summary_does_not_push_the_header_taller(grouped):
+ """It is the one part of the header that grows with what is happening. If
+ it wraps, the header changes height as transfers come and go and every row
+ below it moves — on the narrowest screen, repeatedly."""
+ for width in WIDTHS:
+ head = grouped[str(width)]["boxes"][".transfer-head"]
+ summary = grouped[str(width)]["boxes"][".transfer-head-summary"]
+ assert head["height"] <= 48, (
+ f"at {width} px the header is {head['height']} px tall — it wrapped")
+ assert summary["height"] <= 24, (
+ f"at {width} px the summary wrapped to {summary['height']} px")
+
+
+def test_the_waiting_bar_is_as_wide_as_a_progress_bar(grouped):
+ """A waiting row has no inner fill element — the stripes are on the track
+ itself. Getting that wrong renders a zero-width bar, which reads as a
+ transfer stuck at 0% rather than one that has not started."""
+ for width in WIDTHS:
+ bar = grouped[str(width)]["boxes"][
+ ".transfer-item.transfer-queued .dl-progress"]
+ assert bar["width"] > 100, (
+ f"at {width} px the waiting bar is {bar['width']} px wide")
+ assert bar["height"] >= 3, "the waiting bar has no height"