"""
The legal link at the foot of the sidebar, measured in a browser.
It is pinned to the bottom of the window, not of the page: the sidebar sticks
under the navigation bar at the window's height, so on a long file list the
link is still on screen. And the music bar, pinned to the bottom of the window
as well, must not cover it — the bar publishes its height as `--music-bar-h`
(sticky.js, as the toolbars do), and the sidebar stops above it. That value
is set by hand here; what is under test is the stylesheet's arithmetic.
On a phone the sidebar is the slide-out panel, measured open.
"""
import json
import shutil
import subprocess
import textwrap
from pathlib import Path
import pytest
HARNESS = Path(__file__).parent / "harness" / "layout_probe.py"
STATIC = Path(__file__).resolve().parents[1] / "src" / "meshbay_hub" / "static"
pytestmark = pytest.mark.skipif(
shutil.which("google-chrome") is None or not (STATIC / "style.css").exists(),
reason="Chrome or the SPA stylesheet is not available")
# The probe's frames are this tall.
WINDOW_H = 740
MUSIC_BAR_H = 64
INDEX_DOCK_H = 52
WIDTHS = [390, 1024, 1440]
def _page(music: bool, dock: bool = False) -> str:
groups = "".join(
f'' for i in range(4))
bar = (f'
a track
') if music else ""
# Rendered right before the music bar, as app.js does.
if dock:
bar = (f'indexing
') + bar
props = []
if music:
props.append(f"--music-bar-h:{MUSIC_BAR_H}px")
if dock:
props.append(f"--index-dock-h:{INDEX_DOCK_H}px")
style = f' style="{";".join(props)}"' if props else ""
return textwrap.dedent(f"""
""")
def _measure(tmp_path_factory, music: bool, dock: bool = False) -> dict:
fragment = tmp_path_factory.mktemp("sidebar") / "fragment.html"
fragment.write_text(_page(music, dock), encoding="utf-8")
proc = subprocess.run(
["python3", str(HARNESS), ",".join(str(w) for w in WIDTHS),
str(fragment), ".sidebar-legal", ".sidebar", ".music-player-bar", ".index-dock"],
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
@pytest.fixture(scope="module")
def plain(tmp_path_factory):
return _measure(tmp_path_factory, music=False)
@pytest.fixture(scope="module")
def playing(tmp_path_factory):
return _measure(tmp_path_factory, music=True)
@pytest.fixture(scope="module")
def indexing(tmp_path_factory):
return _measure(tmp_path_factory, music=True, dock=True)
@pytest.mark.parametrize("width", WIDTHS)
def test_the_link_is_at_the_bottom_of_the_window(plain, width):
"""Not at the bottom of a 3000px page, where nobody would find it."""
link = plain[str(width)]["boxes"][".sidebar-legal"]
assert link is not None, "no legal link"
bottom = link["top"] + link["height"]
assert WINDOW_H - 8 <= bottom <= WINDOW_H, (
f"at {width} px the link ends at {bottom}, the window at {WINDOW_H}")
assert link["offLeft"] == 0 and link["offRight"] == 0
@pytest.mark.parametrize("width", WIDTHS)
def test_the_music_bar_does_not_cover_it(playing, width):
link = playing[str(width)]["boxes"][".sidebar-legal"]
bar = playing[str(width)]["boxes"][".music-player-bar"]
assert link is not None and bar is not None
bottom = link["top"] + link["height"]
assert bottom <= bar["top"] + 1, (
f"at {width} px the link ends at {bottom} and the music bar starts at {bar['top']}")
assert bottom >= bar["top"] - 8, (
f"at {width} px the link floats {bar['top'] - bottom} px above the music bar")
@pytest.mark.parametrize("width", WIDTHS)
def test_the_indexing_dock_stacks_on_the_music_bar_and_covers_nothing(indexing, width):
"""The dock (index-dock.js) pins right above the music bar, off
`--music-bar-h`, and the sidebar stops above both."""
link = indexing[str(width)]["boxes"][".sidebar-legal"]
dock = indexing[str(width)]["boxes"][".index-dock"]
bar = indexing[str(width)]["boxes"][".music-player-bar"]
assert link is not None and dock is not None and bar is not None
assert abs(bar["top"] + bar["height"] - WINDOW_H) <= 1, (
f"at {width} px the music bar ends at {bar['top'] + bar['height']}")
assert abs(dock["top"] + dock["height"] - bar["top"]) <= 1, (
f"at {width} px the dock ends at {dock['top'] + dock['height']} "
f"and the music bar starts at {bar['top']}")
bottom = link["top"] + link["height"]
assert dock["top"] - 8 <= bottom <= dock["top"] + 1, (
f"at {width} px the link ends at {bottom} and the dock starts at {dock['top']}")