← Commit history
battery: poll-based back/forward assertions (fixed sample raced slower boxes)
1 file changed
+14−2
tools/verb-battery.mjs+14−2@@ -92,8 +92,10 @@ const T = { // navigation navigate: () => { const r = call('nbrowser_navigate', { sessionId: SID, url: `${HARNESS}?cb=${CB}&nav=2` }); return A(r.ok !== false, 'navigated', JSON.stringify(r).slice(0, 140)); }, reload: () => { const r = call('nbrowser_reload', { sessionId: SID }); return A(r.ok !== false, 'reloaded', JSON.stringify(r).slice(0, 120)); },- back: () => { call('nbrowser_wait', { sessionId: SID, ms: 800 }); const r = call('nbrowser_back', { sessionId: SID }); call('nbrowser_wait', { sessionId: SID, ms: 800 }); const u = evalIn('location.search'); return A(String(u.result).includes('cb=' + CB) && !String(u.result).includes('nav=2'), 'went back', `url after back: ${u.result}`); },- forward: () => { const r = call('nbrowser_forward', { sessionId: SID }); call('nbrowser_wait', { sessionId: SID, ms: 800 }); const u = evalIn('location.search'); return A(String(u.result).includes('nav=2'), 'went forward', `url after forward: ${u.result}`); },+ // back/forward POLL for the expected URL instead of sampling once - the fixed 800ms sample raced a+ // slower box (ROG failed 'back' while a manual check with a settle passed; history commits are async).+ back: () => { call('nbrowser_wait', { sessionId: SID, ms: 800 }); call('nbrowser_back', { sessionId: SID }); const u = pollUrl((q) => q.includes('cb=' + CB) && !q.includes('nav=2')); return A(u.ok, 'went back', `url after back: ${u.last}`); },+ forward: () => { call('nbrowser_forward', { sessionId: SID }); const u = pollUrl((q) => q.includes('nav=2')); return A(u.ok, 'went forward', `url after forward: ${u.last}`); }, wait: () => { const t0 = Date.now(); call('nbrowser_wait', { sessionId: SID, ms: 700 }); return A(Date.now() - t0 >= 650, `waited ${Date.now() - t0}ms`, 'returned too fast'); }, wait_for: () => { call('nbrowser_click', { sessionId: SID, selector: '#spawn-late' }); const r = call('nbrowser_wait_for', { sessionId: SID, selector: '#late-el', timeoutMs: 6000 }); return A(r.ok === true || r.found === true, 'late element appeared', JSON.stringify(r).slice(0, 140)); }, keepalive: () => { const r = call('nbrowser_keepalive', { sessionId: SID, stop: true }); return A(r.ok !== false, 'keepalive verb responds', JSON.stringify(r).slice(0, 120)); },@@ -275,6 +277,16 @@ function metaCount() { return [...s.slice(i, e + 1).matchAll(/^ {2}nbrowser_[a-z0-9_]+:\s*\{/gm)].length; } +function pollUrl(pred, tries = 8, gapMs = 500) {+ let last = '';+ for (let i = 0; i < tries; i++) {+ const u = evalIn('location.search'); last = String(u.result);+ if (pred(last)) return { ok: true, last };+ call('nbrowser_wait', { sessionId: SID, ms: gapMs });+ }+ return { ok: false, last };+}+ function discoverProfile() { const r = call('nbrowser_profiles', {}); // Discovery failing = the target is unreachable. ABORT here rather than fall back to a guessed