Files
autodoc/tests/unit/click-frames.test.js
T
Iisyourdad 34cc358902
Template tests / tests (push) Successful in 1m48s
Template tests / tests (pull_request) Successful in 1m55s
Never take a post-click screenshot when a pre-click frame exists
The remaining 'captured slightly after the click' reports came from the
fresh-shot fallback, which grabs the screen when the click is processed
(after it). The previous lead change made that fallback *more* likely: a
frame now had to be >=120ms before the click to qualify, so on machines
where the capture stream can't always keep a frame that old buffered, more
clicks fell through to the post-click shot.

Make the click-lead a two-tier preference instead of a hard gate in
selectFrameForClick:
1. newest frame captured at least leadMs before the click (ideal margin), else
2. newest frame captured before the click at all.
Only when no pre-click frame exists does the caller fresh-shot. leadMs is
threaded through the stream backend to the worker so both selection paths
agree. Verified end to end: frames land ~120-170ms before each click,
markers stay at 0.00%, and the 8-click burst still saves all 8.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 08:40:33 -05:00

168 lines
6.9 KiB
JavaScript

'use strict';
const test = require('node:test');
const assert = require('node:assert/strict');
const {
FrameRing,
frameUsableForClick,
selectFrameForClick,
} = require('../../app/click-frames');
function frame(name, { startedAt, capturedAt, mode = 'fullscreen', display = null } = {}) {
return { name, mode, startedAt, capturedAt, display };
}
// ---- FrameRing --------------------------------------------------------------
test('the ring keeps at most `limit` frames and drops the oldest first', () => {
let now = 1000;
const evicted = [];
const ring = new FrameRing({ limit: 2, retentionMs: 60_000, now: () => now, onEvict: (f) => evicted.push(f.name) });
ring.push(frame('a', { capturedAt: 1000 }));
ring.push(frame('b', { capturedAt: 1100 }));
now = 1200;
ring.push(frame('c', { capturedAt: 1200 }));
assert.deepEqual(ring.frames().map((f) => f.name), ['b', 'c']);
assert.deepEqual(evicted, ['a'], 'eviction must release the dropped frame');
assert.equal(ring.latest().name, 'c');
});
test('the ring evicts frames older than the retention window', () => {
let now = 1000;
const ring = new FrameRing({ limit: 10, retentionMs: 500, now: () => now });
ring.push(frame('old', { capturedAt: 1000 }));
now = 2000;
ring.push(frame('new', { capturedAt: 2000 }));
assert.deepEqual(ring.frames().map((f) => f.name), ['new']);
});
test('clear() releases every frame through onEvict', () => {
const evicted = [];
const ring = new FrameRing({ onEvict: (f) => evicted.push(f.name) });
ring.push(frame('a', { capturedAt: Date.now() }));
ring.push(frame('b', { capturedAt: Date.now() }));
ring.clear();
assert.deepEqual(ring.frames(), []);
assert.deepEqual(evicted.sort(), ['a', 'b']);
});
// ---- strict selection -------------------------------------------------------
test('strict mode picks the newest frame completed at or before the click', () => {
const clickAt = 10_000;
const frames = [
frame('older', { startedAt: 9300, capturedAt: 9400 }),
frame('best', { startedAt: 9800, capturedAt: 9900 }),
frame('post-click', { startedAt: 10_050, capturedAt: 10_150 }),
];
const chosen = selectFrameForClick(frames, { clickAt, mode: 'fullscreen', strict: true });
assert.equal(chosen.name, 'best');
});
test('strict mode never accepts a frame whose grab started after the click', () => {
const clickAt = 10_000;
// Even one millisecond after the click, and even via the in-flight path:
// a post-click grab can already show the click's effects.
const f = frame('late', { startedAt: 10_001, capturedAt: 10_200 });
assert.equal(frameUsableForClick(f, { clickAt, strict: true, allowInFlight: true }), false);
assert.equal(selectFrameForClick([f], { clickAt, strict: true }), null);
});
test('strict mode accepts an in-flight frame whose grab started before the click', () => {
const clickAt = 10_000;
const f = frame('in-flight', { startedAt: 9950, capturedAt: 10_300 });
assert.equal(frameUsableForClick(f, { clickAt, strict: true, allowInFlight: true }), true);
assert.equal(frameUsableForClick(f, { clickAt, strict: true, allowInFlight: false }), false,
'a not-yet-needed in-flight frame must not be selected from the buffer path');
});
test('a frame older than maxAgeMs is too stale for the click', () => {
const clickAt = 10_000;
const f = frame('stale', { startedAt: 9000, capturedAt: 9100 });
assert.equal(frameUsableForClick(f, { clickAt, strict: true, maxAgeMs: 600 }), false);
assert.equal(frameUsableForClick(f, { clickAt, strict: true, maxAgeMs: 2000 }), true);
});
test('balanced mode accepts a grab started within the slack window after the click', () => {
const clickAt = 10_000;
const f = frame('slack', { startedAt: 10_100, capturedAt: 10_350 });
assert.equal(frameUsableForClick(f, {
clickAt, strict: false, allowInFlight: true, startSlackMs: 300,
}), true);
assert.equal(frameUsableForClick(f, {
clickAt, strict: true, allowInFlight: true, startSlackMs: 300,
}), false, 'slack acceptance is balanced-mode only');
});
test('frames from another display are rejected when the click position is known', () => {
const clickAt = 10_000;
const left = { bounds: { x: 0, y: 0, width: 1920, height: 1080 } };
const right = { bounds: { x: 1920, y: 0, width: 1920, height: 1080 } };
const f = frame('left-screen', { startedAt: 9900, capturedAt: 9950, display: left });
assert.equal(frameUsableForClick(f, { clickAt, clickPos: { x: 2500, y: 500 } }), false);
assert.equal(frameUsableForClick(f, { clickAt, clickPos: { x: 500, y: 500 } }), true);
const g = frame('right-screen', { startedAt: 9960, capturedAt: 9980, display: right });
assert.equal(selectFrameForClick([f, g], { clickAt, clickPos: { x: 2500, y: 500 } }).name, 'right-screen');
});
test('frames of the wrong capture mode are rejected', () => {
const clickAt = 10_000;
const f = frame('window-grab', { startedAt: 9900, capturedAt: 9950, mode: 'window' });
assert.equal(frameUsableForClick(f, { clickAt, mode: 'fullscreen' }), false);
assert.equal(frameUsableForClick(f, { clickAt, mode: 'window' }), true);
});
test('the click lead prefers a frame captured at least leadMs before the click', () => {
const clickAt = 10_000;
const frames = [
frame('with-margin', { startedAt: 9780, capturedAt: 9800 }), // 200ms before
frame('right-at-click', { startedAt: 9970, capturedAt: 9985 }), // 15ms before
];
const chosen = selectFrameForClick(frames, { clickAt, mode: 'fullscreen', strict: true, leadMs: 120 });
assert.equal(chosen.name, 'with-margin',
'with a lead, the frame clear of the click onset wins over the one right at it');
});
test('the click lead falls back to any pre-click frame rather than forcing a post-click shot', () => {
// The whole point of the two-tier rule: when nothing satisfies the lead,
// we still return a pre-click frame (caller would otherwise fresh-shot
// *after* the click). Only "right-before" exists here.
const clickAt = 10_000;
const frames = [frame('right-before', { startedAt: 9960, capturedAt: 9980 })];
const chosen = selectFrameForClick(frames, { clickAt, mode: 'fullscreen', strict: true, leadMs: 120 });
assert.equal(chosen.name, 'right-before');
});
test('the click lead still returns null when no frame precedes the click at all', () => {
const clickAt = 10_000;
const frames = [frame('after', { startedAt: 10_050, capturedAt: 10_080 })];
assert.equal(selectFrameForClick(frames, { clickAt, strict: true, leadMs: 120 }), null,
'a post-click frame is never selected; the caller takes the fresh-shot fallback');
});
test('a frame without startedAt falls back to capturedAt for the strict check', () => {
const clickAt = 10_000;
const before = frame('legacy-before', { capturedAt: 9950 });
const after = frame('legacy-after', { capturedAt: 10_050 });
assert.equal(frameUsableForClick(before, { clickAt, strict: true }), true);
assert.equal(frameUsableForClick(after, { clickAt, strict: true, allowInFlight: true }), false);
});