fix(rig): verify-pending-updates.sh cannot pass on an empty site list; numeric-safe comparison; earlier cleanup trap
The gate could pass vacuously. Every site-list read went through a bare `ROWS=$(site_rows)` with neither the exit status nor the row count checked, and an empty result satisfied every downstream assertion for free: no rows means no malformed hash for B1/B2 to report, and a diff of two empty strings is no difference at all for C1/D2. A down management API would therefore have read as a clean gate. Reads now go through read_rows, which fails loudly on a non-zero CLI exit (site_rows exits 2 on an empty list, and pipefail surfaces a failed call) and aborts unless the line count equals the site count established in step A — keeping the running tally so the abort still prints PASS/FAIL. Verified against an unreachable URL: FAIL 1, exit 1. The join(1)/cut/diff comparisons assumed lexicographic id order matches numeric order, which breaks once a site id reaches 10 alongside single-digit ids (and BSD join silently drops the unmatched rows rather than complaining). Replaced with a python3 comparison keyed by integer id that also asserts the id SETS match, so a site appearing or vanishing between two reads invalidates the comparison instead of quietly shrinking it. Same for the summary table. Also: set -euo pipefail like every sibling script (the cmd && pass || fail guards keep -e safe, and -e does not cover var=$(cmd) — hence the explicit checks above); the cleanup trap is armed BEFORE the shared-script create and falls back to finding the probe by its unique name, so a create that succeeds server-side but whose id we fail to parse can no longer orphan a probe; mktemp instead of /tmp/pu-deploy.$$. PendingUpdatesTests: the rail-scroll check asserted scrollHeight >= clientHeight, which holds for every element. It now asserts what the pane is actually for — the pane is bounded by the viewport and the rail footer holding the indicator stays on screen, so a nav that grows the rail instead of scrolling fails. Live values are genuinely overflowing (scrollHeight 1196 vs clientHeight 680, footer bottom 765 of 900), so the assertion has real content. Re-run against the rig: PASS 13 / FAIL 0; Playwright 3/3. Claude-Session: https://claude.ai/code/session_01Y5ef34iUUMjmwnMpL9xgmB
This commit is contained in:
@@ -134,12 +134,27 @@ public class PendingUpdatesTests
|
||||
var overflowY = await scroll.EvaluateAsync<string>("el => getComputedStyle(el).overflowY");
|
||||
Assert.Equal("auto", overflowY);
|
||||
|
||||
// Informational rather than asserted: scrollHeight >= clientHeight holds for any element,
|
||||
// and whether the nav actually overflows depends on the signed-in user's visible sections.
|
||||
// The point of the pane is that a long nav scrolls INSIDE it instead of growing the rail
|
||||
// and carrying the footer off-screen. Assert that: the pane is bounded by the viewport,
|
||||
// and the rail footer (which holds the indicator this feature adds) stays within it.
|
||||
// scrollHeight >= clientHeight is NOT asserted — that holds for every element.
|
||||
var metrics = await scroll.EvaluateAsync<int[]>(
|
||||
"el => [el.scrollHeight, el.clientHeight]");
|
||||
"el => [el.scrollHeight, el.clientHeight, Math.round(el.getBoundingClientRect().bottom)]");
|
||||
_output.WriteLine(
|
||||
$"rail-scroll: scrollHeight={metrics[0]} clientHeight={metrics[1]} bottom={metrics[2]} (viewport 900)");
|
||||
Assert.True(
|
||||
metrics[0] >= metrics[1],
|
||||
$"rail scroll pane has scrollHeight {metrics[0]} < clientHeight {metrics[1]}");
|
||||
metrics[1] > 0 && metrics[1] <= 900,
|
||||
$"rail scroll pane should be bounded by the 900px viewport, clientHeight was {metrics[1]}");
|
||||
Assert.True(
|
||||
metrics[2] <= 900,
|
||||
$"rail scroll pane overflows the viewport (bottom {metrics[2]} > 900) — the nav is growing the rail instead of scrolling");
|
||||
|
||||
// The footer the indicator lives in must be on-screen, below the pane.
|
||||
var footer = page.Locator(".rail-updates");
|
||||
var footerBottom = await footer.EvaluateAsync<int>(
|
||||
"el => Math.round(el.getBoundingClientRect().bottom)");
|
||||
Assert.True(
|
||||
footerBottom <= 900,
|
||||
$"rail footer is off-screen (bottom {footerBottom} > 900) — the scroll pane is not containing the nav");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user