ps: auto-derive years of service from join year + retirement age
No files matched your search
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"http_code": "200",
|
||||
"has_marker": true,
|
||||
"app_has_override_state": true,
|
||||
"app_has_usecalc_button": true,
|
||||
"i18n_has_fr_auto_hint": true,
|
||||
"engine_has_autoServiceYears": true,
|
||||
"sizes": {
|
||||
"app": 53443,
|
||||
"i18n": 39173,
|
||||
"ps": 12254
|
||||
},
|
||||
"checked_at": "2026-10-09T19:41:54Z",
|
||||
"vantage": "trouble@100.96.20.61 (Midhurst, off-LAN)",
|
||||
"all_ok": true
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
[
|
||||
{
|
||||
"check": "EN auto: input prefilled 41 (age 45, joined 2005, retire 65) \u2014 untouched",
|
||||
"pass": true,
|
||||
"extra": "41"
|
||||
},
|
||||
{
|
||||
"check": "EN auto: derivation hint",
|
||||
"pass": true,
|
||||
"extra": "Calculated: joined 2005 at age 24, retiring at 65 \u2192 41 years of service. Adjust only if you bought past service."
|
||||
},
|
||||
{
|
||||
"check": "EN auto: Next enabled + Use-calculated hidden",
|
||||
"pass": true,
|
||||
"extra": "disabled=False uc_visible=False"
|
||||
},
|
||||
{
|
||||
"check": "EN-auto-step: no horizontal overflow at 390px",
|
||||
"pass": true,
|
||||
"extra": "{'iw': 390, 'docScrollW': 390, 'f1': {'top': 254, 'bottom': 306, 'left': 25, 'right': 365, 'w': 340}, 'next': {'top': 536, 'bottom': 586, 'left': 24, 'right': 390, 'w': 366}, 'uc':"
|
||||
},
|
||||
{
|
||||
"check": "EN-auto-step: #f1 in viewport",
|
||||
"pass": true,
|
||||
"extra": "{'top': 254, 'bottom': 306, 'left': 25, 'right': 365, 'w': 340}"
|
||||
},
|
||||
{
|
||||
"check": "EN-auto-step: #btn-next in viewport",
|
||||
"pass": true,
|
||||
"extra": "{'top': 536, 'bottom': 586, 'left': 24, 'right': 390, 'w': 366}"
|
||||
},
|
||||
{
|
||||
"check": "EN override (real typing): hint LIVE-swaps to override + auto",
|
||||
"pass": true,
|
||||
"extra": "Using your value (30 years). The calculation from your join year gives 41 years."
|
||||
},
|
||||
{
|
||||
"check": "EN override: \"Use calculated\" button becomes visible",
|
||||
"pass": true,
|
||||
"extra": ""
|
||||
},
|
||||
{
|
||||
"check": "EN override: persisted psServiceOverride = 30",
|
||||
"pass": true,
|
||||
"extra": "30"
|
||||
},
|
||||
{
|
||||
"check": "EN-override-step: no horizontal overflow at 390px",
|
||||
"pass": true,
|
||||
"extra": "{'iw': 390, 'docScrollW': 390, 'f1': {'top': 254, 'bottom': 306, 'left': 25, 'right': 365, 'w': 340}, 'next': {'top': 536, 'bottom': 586, 'left': 24, 'right': 390, 'w': 366}, 'uc':"
|
||||
},
|
||||
{
|
||||
"check": "EN-override-step: #f1 in viewport",
|
||||
"pass": true,
|
||||
"extra": "{'top': 254, 'bottom': 306, 'left': 25, 'right': 365, 'w': 340}"
|
||||
},
|
||||
{
|
||||
"check": "EN-override-step: #btn-next in viewport",
|
||||
"pass": true,
|
||||
"extra": "{'top': 536, 'bottom': 586, 'left': 24, 'right': 390, 'w': 366}"
|
||||
},
|
||||
{
|
||||
"check": "EN use-calc: prefill back to 41 + auto hint",
|
||||
"pass": true,
|
||||
"extra": "41 | Calculated: joined 2005 at age 24, retiring at 65 \u2192 41 years of service. Adjust only if yo"
|
||||
},
|
||||
{
|
||||
"check": "EN use-calc: override cleared in localStorage",
|
||||
"pass": true,
|
||||
"extra": "None"
|
||||
},
|
||||
{
|
||||
"check": "EN use-calc: button hidden again",
|
||||
"pass": true,
|
||||
"extra": ""
|
||||
},
|
||||
{
|
||||
"check": "EN results (override 30): 30 years used",
|
||||
"pass": true,
|
||||
"extra": "Your federal public service pension\nGroup 1 (rules from your join year)\t\nPensionable service used: 30 years (max 35)\t\n5-year average salary (highest paid)\t$108,"
|
||||
},
|
||||
{
|
||||
"check": "EN results (override 30): from-65 51,006.90",
|
||||
"pass": true,
|
||||
"extra": "Your federal public service pension\nGroup 1 (rules from your join year)\t\nPensionable service used: 30 years (max 35)\t\n5-year average salary (highest paid)\t$108,"
|
||||
},
|
||||
{
|
||||
"check": "EN-results: no horizontal overflow at 390px",
|
||||
"pass": true,
|
||||
"extra": "{'iw': 390, 'docScrollW': 390, 'f1': None, 'next': {'top': 0, 'bottom': 0, 'left': 0, 'right': 0, 'w': 0}, 'uc': None, 'card': {'top': 1933, 'bottom': 2732, 'left': 16, 'right': 37"
|
||||
},
|
||||
{
|
||||
"check": "EN-results: #btn-next in viewport",
|
||||
"pass": true,
|
||||
"extra": "{'top': 0, 'bottom': 0, 'left': 0, 'right': 0, 'w': 0}"
|
||||
},
|
||||
{
|
||||
"check": "EN-results: ps-card fits the viewport",
|
||||
"pass": true,
|
||||
"extra": "{'top': 1933, 'bottom': 2732, 'left': 16, 'right': 374, 'w': 358}"
|
||||
},
|
||||
{
|
||||
"check": "EN results (auto): 35 years used (auto 41, cap 35)",
|
||||
"pass": true,
|
||||
"extra": "Your federal public service pension\nGroup 1 (rules from your join year)\t\nPensionable service used: 35 years (max 35)\t\n5-year average salary (highest paid)\t$108,"
|
||||
},
|
||||
{
|
||||
"check": "EN results (auto): from-65 59,508.05",
|
||||
"pass": true,
|
||||
"extra": "Your federal public service pension\nGroup 1 (rules from your join year)\t\nPensionable service used: 35 years (max 35)\t\n5-year average salary (highest paid)\t$108,"
|
||||
},
|
||||
{
|
||||
"check": "FR auto: prefilled 41",
|
||||
"pass": true,
|
||||
"extra": "41"
|
||||
},
|
||||
{
|
||||
"check": "FR auto: derivation hint",
|
||||
"pass": true,
|
||||
"extra": "Calcul\u00e9 : entr\u00e9e en poste en 2005 \u00e0 24 ans, d\u00e9part \u00e0 65 ans \u2192 41 ann\u00e9es de service. \u00c0 ajuster seulement si vous avez achet\u00e9 des services ant\u00e9rieurs."
|
||||
},
|
||||
{
|
||||
"check": "FR override: hint",
|
||||
"pass": true,
|
||||
"extra": "Votre valeur (30 ann\u00e9es) est utilis\u00e9e. Le calcul \u00e0 partir de votre ann\u00e9e d\u2019entr\u00e9e donne 41 ans."
|
||||
},
|
||||
{
|
||||
"check": "FR override: \"Utiliser le calcul\" visible",
|
||||
"pass": true,
|
||||
"extra": "{'display': 'block', 'vis': 'visible', 'box': [340, 20.921875], 'lang': 'fr'}"
|
||||
},
|
||||
{
|
||||
"check": "FR results (auto): 35 ann\u00e9es (max 35)",
|
||||
"pass": true,
|
||||
"extra": "Votre pension de la fonction publique f\u00e9d\u00e9rale\nGroupe 1 (r\u00e8gles selon votre ann\u00e9e d\u2019adh\u00e9sion)\t\nService ouvrant droit \u00e0 pension retenu : 35 ann\u00e9es (max 35)\t\nSala"
|
||||
},
|
||||
{
|
||||
"check": "FR results (auto): 59 508,05 formatted fr-CA",
|
||||
"pass": true,
|
||||
"extra": "Votre pension de la fonction publique f\u00e9d\u00e9rale\nGroupe 1 (r\u00e8gles selon votre ann\u00e9e d\u2019adh\u00e9sion)\t\nService ouvrant droit \u00e0 pension retenu : 35 ann\u00e9es (max 35)\t\nSala"
|
||||
},
|
||||
{
|
||||
"check": "FR results (override): 30 ann\u00e9es + 51 006,90",
|
||||
"pass": true,
|
||||
"extra": "Votre pension de la fonction publique f\u00e9d\u00e9rale\nGroupe 1 (r\u00e8gles selon votre ann\u00e9e d\u2019adh\u00e9sion)\t\nService ouvrant droit \u00e0 pension retenu : 30 ann\u00e9es (max 35)\t\nSalaire moyen sur 5 ans "
|
||||
},
|
||||
{
|
||||
"check": "FR-results: no horizontal overflow at 390px",
|
||||
"pass": true,
|
||||
"extra": "{'iw': 390, 'docScrollW': 390, 'f1': None, 'next': {'top': 0, 'bottom': 0, 'left': 0, 'right': 0, 'w': 0}, 'uc': None, 'card': {'top': 1956, 'bottom': 2883, 'left': 16, 'right': 37"
|
||||
},
|
||||
{
|
||||
"check": "FR-results: #btn-next in viewport",
|
||||
"pass": true,
|
||||
"extra": "{'top': 0, 'bottom': 0, 'left': 0, 'right': 0, 'w': 0}"
|
||||
},
|
||||
{
|
||||
"check": "FR-results: ps-card fits the viewport",
|
||||
"pass": true,
|
||||
"extra": "{'top': 1956, 'bottom': 2883, 'left': 16, 'right': 374, 'w': 358}"
|
||||
},
|
||||
{
|
||||
"check": "module OFF: 15 steps (last = 15/15)",
|
||||
"pass": true,
|
||||
"extra": "15 / 15"
|
||||
},
|
||||
{
|
||||
"check": "module OFF: no PS quiz text on results, card hidden",
|
||||
"pass": true,
|
||||
"extra": "[]"
|
||||
}
|
||||
]
|
||||
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 248 KiB |
|
After Width: | Height: | Size: 247 KiB |
|
After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 254 KiB |
|
After Width: | Height: | Size: 237 KiB |
@@ -0,0 +1,61 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Off-LAN check for the PS auto-service deploy (2026-10-09), via the Midhurst troublebox.
|
||||
Verifies 200 + marker + served files carry the auto-service feature:
|
||||
app.js → psServiceOverride ; i18n.js → FR auto hint string ; engine/pspension.js → autoServiceYears.
|
||||
Writes audit/ps-auto-offlan-check.json, prints OFFLAN-OK/FAIL."""
|
||||
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")
|
||||
app = run(f"curl -s {URL}app.js --max-time 30 | head -c 500000")
|
||||
i18n = run(f"curl -s {URL}i18n.js --max-time 30 | head -c 500000")
|
||||
ps = run(f"curl -s {URL}engine/pspension.js --max-time 30 | head -c 500000")
|
||||
conn.close()
|
||||
|
||||
checks = {
|
||||
"http_code": code,
|
||||
"has_marker": "retire-planner v1" in html,
|
||||
"app_has_override_state": "psServiceOverride" in app,
|
||||
"app_has_usecalc_button": "ps-usecalc" in app,
|
||||
"i18n_has_fr_auto_hint": "entr" in i18n and "ann" in i18n and "de service. " in i18n and "Calcul" in i18n,
|
||||
"engine_has_autoServiceYears": "autoServiceYears" in ps,
|
||||
"sizes": {"app": len(app), "i18n": len(i18n), "ps": len(ps)},
|
||||
"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["app_has_override_state"]
|
||||
and checks["app_has_usecalc_button"] and checks["i18n_has_fr_auto_hint"]
|
||||
and checks["engine_has_autoServiceYears"])
|
||||
with open("audit/ps-auto-offlan-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()
|
||||
@@ -0,0 +1,169 @@
|
||||
#!/usr/bin/env python3
|
||||
"""PS-AUTO-SERVICE live UI audit — local server (site/) at 390x844, EN + FR.
|
||||
Phases (each = seeded localStorage + reload, plus real keyboard interaction):
|
||||
1 ps_service prefilled with the auto value + derivation hint, Next enabled, no button
|
||||
2 real typing of an override (30) → override hint + "Use calculated" button
|
||||
3 "Use calculated" restores the auto prefill + clears the override in localStorage
|
||||
4 results card reflects the override (30 years · 51,006.90 / 51 506,90 FR)
|
||||
5 results card reflects the auto value (35 years cap · 59,508.05 / 59 508,05 FR)
|
||||
6 FR wording for 1/2/5
|
||||
7 module OFF parity: 15 steps, no PS text anywhere
|
||||
8 app-shell geometry at 390px: no horizontal overflow, controls + ps-card in view
|
||||
Writes audit/ps-auto-service/*.png + checks.json, prints PS-AUTO-AUDIT-OK/FAIL.
|
||||
"""
|
||||
import json, os, re, sys
|
||||
from playwright.sync_api import sync_playwright
|
||||
|
||||
OUT = 'audit/ps-auto-service'
|
||||
os.makedirs(OUT, exist_ok=True)
|
||||
CHROME = '/usr/bin/google-chrome'
|
||||
BASE = os.environ.get('AUDIT_BASE', 'http://127.0.0.1:8801/')
|
||||
LS = 'retire-planner-v1'
|
||||
|
||||
BASE_A = {
|
||||
"province": "ON", "age": 45, "retireAge": 65, "household": "single",
|
||||
"partner": {"age": 45, "income": 0, "rrsp": 0, "tfsa": 0, "nonreg": 0, "monthlyContribution": 0},
|
||||
"income": 60000, "rrsp": 100000, "tfsa": 30000, "nonreg": 20000,
|
||||
"monthlyContribution": 500, "employerMatchMonthly": 0,
|
||||
"spendingAnnual": 50000, "cppStartAge": 65, "oasStartAge": 65,
|
||||
"pensionAnnual": 0, "rentalAnnual": 0, "otherAnnual": 0,
|
||||
"psPension": True, "psJoinYear": 2005, "psServiceOverride": None, "psAvgSalary": 108324,
|
||||
"psOccupation": "it", "psItLevel": "IT-03", "psItStep": 3,
|
||||
"realReturnPre": 3.5, "realReturnPost": 2.5, "inflation": 2.0, "lifeExp": 95,
|
||||
"interests": [],
|
||||
}
|
||||
|
||||
GEO_JS = """() => {
|
||||
const de = document.scrollingElement;
|
||||
const r = (s) => { const e = document.querySelector(s); if (!e) return null; const b = e.getBoundingClientRect();
|
||||
return {top: Math.round(b.top), bottom: Math.round(b.bottom), left: Math.round(b.left), right: Math.round(b.right), w: Math.round(b.width)}; };
|
||||
return { iw: innerWidth, docScrollW: de.scrollWidth,
|
||||
f1: r('#f1'), next: r('#btn-next'), uc: r('#ps-usecalc'), card: r('#ps-card') };
|
||||
}"""
|
||||
|
||||
results, fails = [], 0
|
||||
def ok(name, cond, extra=''):
|
||||
global fails
|
||||
results.append({'check': name, 'pass': bool(cond), 'extra': str(extra)[:180]})
|
||||
if not cond: fails += 1
|
||||
print((' PASS ' if cond else ' FAIL ') + name + ((' [' + str(extra)[:150] + ']') if extra and not cond else ''))
|
||||
|
||||
def nb(s):
|
||||
return s.replace('\u00a0', ' ').replace('\u202f', ' ')
|
||||
|
||||
def seed(page, a, step, screen, lang):
|
||||
page.evaluate("""([ls, st]) => localStorage.setItem(ls, JSON.stringify(st))""", (LS, {'a': a, 'step': step, 'screen': screen, 'lang': lang}))
|
||||
page.reload(wait_until='load')
|
||||
page.wait_for_timeout(250)
|
||||
|
||||
def geo_checks(tag, g, need_card=False):
|
||||
ok(tag + ': no horizontal overflow at 390px', g['docScrollW'] <= g['iw'] + 1, g)
|
||||
if g['f1']:
|
||||
ok(tag + ': #f1 in viewport', g['f1']['top'] >= 0 and g['f1']['bottom'] <= g['iw'] * 3, g['f1'])
|
||||
if g['next']:
|
||||
ok(tag + ': #btn-next in viewport', 0 <= g['next']['top'] and g['next']['bottom'] <= 844, g['next'])
|
||||
if need_card:
|
||||
ok(tag + ': ps-card fits the viewport', g['card'] and g['card']['right'] <= g['iw'] + 1 and g['card']['left'] >= 0, g['card'])
|
||||
|
||||
with sync_playwright() as pw:
|
||||
browser = pw.chromium.launch(executable_path=CHROME, args=['--no-sandbox'])
|
||||
page = browser.new_page(viewport={'width': 390, 'height': 844})
|
||||
page.goto(BASE, wait_until='load')
|
||||
|
||||
# ---- EN 1: auto prefill, untouched ----
|
||||
seed(page, dict(BASE_A), 13, 'quiz', 'en')
|
||||
v = page.input_value('#f1')
|
||||
hint = nb(page.inner_text('#step-body .hint'))
|
||||
dis = page.is_disabled('#btn-next')
|
||||
uc_vis = page.is_visible('#ps-svc-reset')
|
||||
ok('EN auto: input prefilled 41 (age 45, joined 2005, retire 65) — untouched', v == '41', v)
|
||||
ok('EN auto: derivation hint', re.search(r'Calculated: joined 2005 at age 24, retiring at 65 . 41 years of service', hint), hint)
|
||||
ok('EN auto: Next enabled + Use-calculated hidden', dis is False and uc_vis is False, f'disabled={dis} uc_visible={uc_vis}')
|
||||
geo_checks('EN-auto-step', page.evaluate(GEO_JS))
|
||||
page.screenshot(path=OUT + '/en-auto-step.png')
|
||||
|
||||
# ---- EN 2: real typing → override (hint must LIVE-swap, no re-render in a real browser) ----
|
||||
page.fill('#f1', '30')
|
||||
page.wait_for_timeout(150)
|
||||
hint2 = nb(page.inner_text('#step-body .hint'))
|
||||
st = page.evaluate("ls => JSON.parse(localStorage.getItem(ls))", LS)
|
||||
ok('EN override (real typing): hint LIVE-swaps to override + auto', re.search(r'Using your value \(30 years\).*gives 41 years', hint2, re.S), hint2)
|
||||
ok('EN override: "Use calculated" button becomes visible', page.is_visible('#ps-svc-reset'),
|
||||
page.evaluate("() => document.querySelector('#ps-svc-reset').style.display"))
|
||||
ok('EN override: persisted psServiceOverride = 30', st['a'].get('psServiceOverride') == 30, st['a'].get('psServiceOverride'))
|
||||
geo_checks('EN-override-step', page.evaluate(GEO_JS))
|
||||
page.screenshot(path=OUT + '/en-override-step.png')
|
||||
|
||||
# ---- EN 3: use-calc restores auto ----
|
||||
page.click('#ps-usecalc')
|
||||
page.wait_for_timeout(250)
|
||||
v3 = page.input_value('#f1')
|
||||
hint3 = nb(page.inner_text('#step-body .hint'))
|
||||
st3 = page.evaluate("ls => JSON.parse(localStorage.getItem(ls))", LS)
|
||||
ok('EN use-calc: prefill back to 41 + auto hint', v3 == '41' and 'Calculated: joined 2005' in hint3, f'{v3} | {hint3[:90]}')
|
||||
ok('EN use-calc: override cleared in localStorage', st3['a'].get('psServiceOverride') is None, st3['a'].get('psServiceOverride'))
|
||||
ok('EN use-calc: button hidden again', page.is_visible('#ps-svc-reset') is False)
|
||||
|
||||
# ---- EN 4/5: results reflect override vs auto ----
|
||||
seed(page, dict(BASE_A, psServiceOverride=30), 0, 'results', 'en')
|
||||
card = nb(page.inner_text('#ps-card'))
|
||||
ok('EN results (override 30): 30 years used', re.search(r'30 years \(max 35\)', card), card[:160])
|
||||
ok('EN results (override 30): from-65 51,006.90', '51,006.90' in card, card[:160])
|
||||
geo_checks('EN-results', page.evaluate(GEO_JS), need_card=True)
|
||||
page.screenshot(path=OUT + '/en-results-override.png')
|
||||
|
||||
seed(page, dict(BASE_A), 0, 'results', 'en')
|
||||
card2 = nb(page.inner_text('#ps-card'))
|
||||
ok('EN results (auto): 35 years used (auto 41, cap 35)', re.search(r'35 years \(max 35\)', card2), card2[:160])
|
||||
ok('EN results (auto): from-65 59,508.05', '59,508.05' in card2, card2[:160])
|
||||
page.screenshot(path=OUT + '/en-results-auto.png')
|
||||
|
||||
# ---- FR 6: wording ----
|
||||
seed(page, dict(BASE_A), 13, 'quiz', 'fr')
|
||||
vf = page.input_value('#f1')
|
||||
hintF = nb(page.inner_text('#step-body .hint'))
|
||||
ok('FR auto: prefilled 41', vf == '41', vf)
|
||||
ok('FR auto: derivation hint', re.search(r'Calcul. : entr.e en poste en 2005 . 24 ans, d.part . 65 ans . 41 ann.es de service', hintF), hintF)
|
||||
page.fill('#f1', '30')
|
||||
page.wait_for_timeout(150)
|
||||
hintF2 = nb(page.inner_text('#step-body .hint'))
|
||||
ucf = page.query_selector('#ps-usecalc')
|
||||
ok('FR override: hint', re.search(r'Votre valeur \(30 ann.es\) est utilis.e.*donne 41 ans', hintF2, re.S), hintF2)
|
||||
ok('FR override: "Utiliser le calcul" visible', page.is_visible('#ps-svc-reset') and 'calcul' in ucf.inner_text().lower(),
|
||||
page.evaluate("""() => { const e = document.querySelector('#ps-svc-reset');
|
||||
const cs = getComputedStyle(e), b = e.getBoundingClientRect();
|
||||
return { display: cs.display, vis: cs.visibility, box: [b.width, b.height],
|
||||
lang: document.documentElement.lang }; }"""))
|
||||
page.screenshot(path=OUT + '/fr-override-step.png')
|
||||
seed(page, dict(BASE_A), 0, 'results', 'fr')
|
||||
cardF = nb(page.inner_text('#ps-card'))
|
||||
ok('FR results (auto): 35 années (max 35)', re.search(r'35 ann.es \(max 35\)', cardF), cardF[:160])
|
||||
ok('FR results (auto): 59 508,05 formatted fr-CA', re.search(r'59\s?508,05', cardF), cardF[:160])
|
||||
seed(page, dict(BASE_A, psServiceOverride=30), 0, 'results', 'fr')
|
||||
cardFO = nb(page.inner_text('#ps-card'))
|
||||
ok('FR results (override): 30 années + 51 006,90', re.search(r'30 ann.es \(max 35\)', cardFO) and re.search(r'51\s?006,90', cardFO), cardFO[:200])
|
||||
geo_checks('FR-results', page.evaluate(GEO_JS), need_card=True)
|
||||
page.screenshot(path=OUT + '/fr-results-override.png')
|
||||
|
||||
# ---- 7: module OFF parity (15 steps, no PS text) ----
|
||||
seed(page, dict(BASE_A, psPension=False, psJoinYear=None, psServiceOverride=None, psAvgSalary=None,
|
||||
psOccupation=None, psItLevel=None, psItStep=0), 14, 'quiz', 'en')
|
||||
sc = nb(page.inner_text('#step-count'))
|
||||
ok('module OFF: 15 steps (last = 15/15)', re.search(r'15\s*/\s*15|15 of 15|of 15', sc), sc)
|
||||
page.click('#btn-next')
|
||||
page.wait_for_timeout(400)
|
||||
body_all = nb(page.inner_text('body')).lower()
|
||||
# parity: no PS QUIZ content (the static results footer "…pension (PSSA) modelled when enabled" predates this change)
|
||||
ok('module OFF: no PS quiz text on results, card hidden',
|
||||
('pensionable' not in body_all and 'years of pensionable' not in body_all and
|
||||
page.evaluate("() => document.querySelector('#ps-card').hidden") is True),
|
||||
[w for w in ('pensionable', 'years of pensionable service') if w in body_all])
|
||||
page.screenshot(path=OUT + '/module-off-results.png')
|
||||
|
||||
browser.close()
|
||||
|
||||
with open(OUT + '/checks.json', 'w') as f:
|
||||
json.dump(results, f, indent=1)
|
||||
print(f"\n{len(results)} checks, {fails} failed")
|
||||
print('PS-AUTO-AUDIT-OK' if fails == 0 else 'PS-AUTO-AUDIT-FAIL')
|
||||
sys.exit(1 if fails else 0)
|
||||