Fix PS module stuck-Next bug: validate() on number-input oninput (typing into empty PS join/service/salary step never enabled Next; real users were stuck) + click-through regression test (smoke 74->88, EN+FR)
This commit is contained in:
1 parent
bef1f9e3df
commit
ed37f82511
2 files changed
+51
-4
No files matched your search
+2
-2
@@ -369,13 +369,13 @@
|
|||||||
});
|
});
|
||||||
var f1 = $('#f1');
|
var f1 = $('#f1');
|
||||||
if (f1) {
|
if (f1) {
|
||||||
f1.oninput = function () { s.set(f1.value); save(); liveUpdate(); if (s.type === 'slider') $('#sv').textContent = s.fmt(+f1.value); };
|
f1.oninput = function () { s.set(f1.value); save(); liveUpdate(); validate(s); if (s.type === 'slider') $('#sv').textContent = s.fmt(+f1.value); };
|
||||||
if (s.type === 'slider') f1.oninput();
|
if (s.type === 'slider') f1.oninput();
|
||||||
/* Fix 8: Enter on a number step = press Next (when enabled). */
|
/* Fix 8: Enter on a number step = press Next (when enabled). */
|
||||||
if (s.type === 'number') f1.onkeydown = function (e) { if (e.key === 'Enter' && !btnNext.disabled) btnNext.click(); };
|
if (s.type === 'number') f1.onkeydown = function (e) { if (e.key === 'Enter' && !btnNext.disabled) btnNext.click(); };
|
||||||
}
|
}
|
||||||
stepBody.querySelectorAll('input[type=number][data-k]').forEach(function (inp) {
|
stepBody.querySelectorAll('input[type=number][data-k]').forEach(function (inp) {
|
||||||
inp.oninput = function () { s.set(inp.dataset.k, inp.value); save(); liveUpdate(); };
|
inp.oninput = function () { s.set(inp.dataset.k, inp.value); save(); liveUpdate(); validate(s); };
|
||||||
});
|
});
|
||||||
stepBody.querySelectorAll('input[type=range][data-k]').forEach(function (inp) {
|
stepBody.querySelectorAll('input[type=range][data-k]').forEach(function (inp) {
|
||||||
inp.oninput = function () {
|
inp.oninput = function () {
|
||||||
|
|||||||
+49
-2
@@ -201,16 +201,63 @@ function runPs(lang, M, done) {
|
|||||||
}, 400);
|
}, 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* PS module quiz click-through — regression test (2026-10-09): typing into an initially-empty
|
||||||
|
PS number step (join year / service / salary) MUST re-enable Next. Pre-fix, renderStep validated
|
||||||
|
only at render, so the button stayed disabled and a real user was STUCK on the join step. */
|
||||||
|
function runPsQuiz(lang, done) {
|
||||||
|
console.log('\n--- ' + lang.toUpperCase() + ' (PS quiz click-through) ---');
|
||||||
|
load(lang);
|
||||||
|
setTimeout(() => {
|
||||||
|
const opt = makeEl('opt'); opt.dataset.v = 'ON';
|
||||||
|
q('#step-body').querySelectorAll = (sel) => (sel === '.opt' ? [opt] : []);
|
||||||
|
click('btn-begin'); // re-render step 0 with patched querySelectorAll
|
||||||
|
const typed = {};
|
||||||
|
let guard = 0, joinDisabledBefore = null;
|
||||||
|
while (guard++ < 40) {
|
||||||
|
const st = JSON.parse(store[LS]);
|
||||||
|
const step = st.step;
|
||||||
|
const next = q('#btn-next');
|
||||||
|
if (step === 0 && !typed.prov) { opt.dataset.v = 'ON'; opt._l.click(); typed.prov = 1; continue; }
|
||||||
|
if (step === 11 && !typed.ps) { typed.ps = 1; opt.dataset.v = 'yes'; opt._l.click();
|
||||||
|
ok('PS toggle: Yes picked', JSON.parse(store[LS]).a.psPension === true); continue; }
|
||||||
|
if (step === 12 && !typed.join) { typed.join = 1; joinDisabledBefore = next.disabled;
|
||||||
|
const f1 = q('#f1'); f1.value = '2005'; f1._l.input && f1._l.input.call(f1);
|
||||||
|
ok('PS join step starts disabled (empty field)', joinDisabledBefore === true, 'disabled=' + joinDisabledBefore);
|
||||||
|
ok('typing into empty PS step enables Next (regression: validate on input)', q('#btn-next').disabled === false, 'after=' + q('#btn-next').disabled);
|
||||||
|
continue; }
|
||||||
|
if (step === 13 && !typed.svc) { typed.svc = 1; const f1 = q('#f1'); f1.value = '30'; f1._l.input && f1._l.input.call(f1); continue; }
|
||||||
|
if (step === 14 && !typed.sal) { typed.sal = 1; const f1 = q('#f1'); f1.value = '90000'; f1._l.input && f1._l.input.call(f1); continue; }
|
||||||
|
if (step === 15 && !typed.occ) { typed.occ = 1; opt.dataset.v = 'it'; opt._l.click(); continue; }
|
||||||
|
if (step === 16) {
|
||||||
|
const a2 = JSON.parse(store[LS]).a;
|
||||||
|
if (!a2.psItLevel) { opt.dataset.v = 'IT-03'; opt._l.click(); continue; }
|
||||||
|
if (!a2.psItStep) { opt.dataset.v = '3'; opt._l.click(); continue; }
|
||||||
|
}
|
||||||
|
if (next.disabled) break;
|
||||||
|
click('btn-next');
|
||||||
|
if (q('#scr-results').hidden === false) break;
|
||||||
|
}
|
||||||
|
const a = JSON.parse(store[LS]).a;
|
||||||
|
ok('PS click-through reached results', q('#scr-results').hidden === false, 'guard=' + guard);
|
||||||
|
ok('PS card rendered after click-through', !!q('#ps-card') && q('#ps-card').hidden === false);
|
||||||
|
ok('PS state persisted (join 2005 / service 30 / IT-03 step 3)',
|
||||||
|
a.psPension === true && a.psJoinYear === 2005 && a.psServiceYears === 30 && a.psOccupation === 'it' && a.psItLevel === 'IT-03' && a.psItStep === 3,
|
||||||
|
JSON.stringify({ j: a.psJoinYear, s: a.psServiceYears, o: a.psOccupation, l: a.psItLevel, st: a.psItStep }));
|
||||||
|
ok('IT step pick pre-filled salary (IT-03 s3 = 108,324)', a.psAvgSalary === 108324, a.psAvgSalary);
|
||||||
|
done();
|
||||||
|
}, 400);
|
||||||
|
}
|
||||||
|
|
||||||
run('en', EN, () => run('fr', FR, () => runPs('en', {
|
run('en', EN, () => run('fr', FR, () => runPs('en', {
|
||||||
psCard: /federal public service pension/, psAt: /60,000/, psFrom: /46,012\.50/,
|
psCard: /federal public service pension/, psAt: /60,000/, psFrom: /46,012\.50/,
|
||||||
psBridge: /13,987\.50/, psSeries: /Public service pension/, psInsight: /covers about/
|
psBridge: /13,987\.50/, psSeries: /Public service pension/, psInsight: /covers about/
|
||||||
}, () => runPs('fr', {
|
}, () => runPs('fr', {
|
||||||
psCard: /pension de la fonction publique fédérale/, psAt: /60[\s\u00a0\u202f]000/, psFrom: /46[\s\u00a0\u202f]012,50/,
|
psCard: /pension de la fonction publique fédérale/, psAt: /60[\s\u00a0\u202f]000/, psFrom: /46[\s\u00a0\u202f]012,50/,
|
||||||
psBridge: /13[\s\u00a0\u202f]987,50/, psSeries: /Pension de la fonction publique/, psInsight: /couvre environ/
|
psBridge: /13[\s\u00a0\u202f]987,50/, psSeries: /Pension de la fonction publique/, psInsight: /couvre environ/
|
||||||
}, () => {
|
}, () => runPsQuiz('en', () => runPsQuiz('fr', () => {
|
||||||
ok('EN privacy line present in index.html', /never leave your browser/.test(fs.readFileSync(path.join(SITE, 'index.html'), 'utf8')));
|
ok('EN privacy line present in index.html', /never leave your browser/.test(fs.readFileSync(path.join(SITE, 'index.html'), 'utf8')));
|
||||||
ok('FR privacy string present in i18n.js', /ne quittent jamais votre navigateur/.test(fs.readFileSync(path.join(SITE, 'i18n.js'), 'utf8')));
|
ok('FR privacy string present in i18n.js', /ne quittent jamais votre navigateur/.test(fs.readFileSync(path.join(SITE, 'i18n.js'), 'utf8')));
|
||||||
console.log(fails ? '\nSMOKE-FAIL: ' + fails + ' of ' + total : '\nSMOKE-OK all ui smoke checks passed (' + total + ')');
|
console.log(fails ? '\nSMOKE-FAIL: ' + fails + ' of ' + total : '\nSMOKE-OK all ui smoke checks passed (' + total + ')');
|
||||||
process.exit(fails ? 1 : 0);
|
process.exit(fails ? 1 : 0);
|
||||||
}))))
|
}))))))
|
||||||
;
|
;
|
||||||
Reference in new issue
Block a user