Files
retire-planner/audit/lang_right_offlan.py
T
krisf 043fa8a683 Header: right-align EN|FR toggle in .hdr-in (top-right of page)
One CSS line: .lang-toggle{order:99;margin-left:auto}. Spec's literal order:99 alone
failed its own <=2px right-edge acceptance (gap 45.6-467.6px, 18/24 cases — order
reorders, .hdr-in is left-packed; geo-literal-order99.json), so margin-left:auto on
the toggle absorbs the free space; pill/logo untouched (spec-forbidden zone respected).

Battery: A1 gap=0px + rightmost + nothing-past-left in 24/24 (320/360/390/1280 x EN/FR
x intro/quiz/results); A2 header height unchanged 56/66px; A3 320px no overflow/wrap,
FR logo ellipsis intact, elementFromPoint hit-tests lang buttons + Start over pass;
A4 FR/EN clicks switch lang+title+aria-pressed; A5 24 screenshots before/after; A6
engine 36 + i18n 48 + smoke 92 + ps-pension 70 green; A7 desktop pixdiff header-strip-
only, 0 px below header at every device, self-jitter bit-identical; A8 DEPLOY-OK,
origin marker=1 + byte-identical CSS, off-LAN troublebox 200+marker+rule OFFLAN-OK.
2026-10-09 13:32:40 -04:00

55 lines
2.1 KiB
Python

#!/usr/bin/env python3
"""Off-LAN check for the header lang-toggle right-align deploy (2026-10-09),
via the Midhurst troublebox. Verifies 200 + marker + served style.css carries the
`.lang-toggle{order:99;margin-left:auto}` rule. Writes audit/lang-right-geo-check.json,
prints OFFLAN-OK."""
import json, sys, time
import paramiko
CANDS = ["b1tvvt07", "ubnt", "admin", "password", "b1tvvt07!", "1234", "root", "glinet"]
URL = "https://retire.krisforbes.ca/"
def main():
conn = None
for pw in CANDS:
c = paramiko.SSHClient()
c.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
c.connect("100.96.20.61", port=2222, username="trouble", password=pw,
timeout=25, banner_timeout=25, auth_timeout=25,
allow_agent=False, look_for_keys=False)
conn = c
break
except Exception:
c.close()
if conn is None:
print("OFFLAN-FAIL: no auth to troublebox")
sys.exit(1)
def run(cmd):
_, out, _ = conn.exec_command(cmd, timeout=60)
return out.read().decode("utf-8", "replace").strip()
code = run(f"curl -s -o /dev/null -w '%{{http_code}}' {URL} --max-time 30")
html = run(f"curl -s {URL} --max-time 30 | head -c 200000")
css = run(f"curl -s {URL}style.css --max-time 30 | head -c 200000")
conn.close()
checks = {
"http_code": code,
"has_marker": "retire-planner v1" in html,
"css_lang_toggle_right": "lang-toggle{order:99;margin-left:auto}" in css,
"css_size": len(css),
"checked_at": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
"vantage": "trouble@100.96.20.61 (Midhurst, off-LAN)",
}
checks["all_ok"] = (code == "200" and checks["has_marker"] and checks["css_lang_toggle_right"])
with open("audit/lang-right-geo-check.json", "w") as f:
json.dump(checks, f, indent=2, ensure_ascii=False)
print(json.dumps(checks, indent=2, ensure_ascii=False))
print("OFFLAN-OK" if checks["all_ok"] else "OFFLAN-FAIL")
sys.exit(0 if checks["all_ok"] else 1)
if __name__ == "__main__":
main()