Fixed an issue where clicking wouldn't line up with screenshot part 3
Template tests / tests (push) Successful in 1m54s

This commit is contained in:
Iisyourdad
2026-06-11 12:38:48 -05:00
parent 0ecc1b473f
commit 42affc571d
2 changed files with 143 additions and 40 deletions
+77 -14
View File
@@ -50,17 +50,46 @@ test('click-triggered session capture uses the low-latency hide pause', async ()
});
});
function makeFrame(name, ageMs = 0) {
function makeFrame(name, ageMs = 0, overrides = {}) {
return {
mode: 'fullscreen',
mode: overrides.mode || 'fullscreen',
png: Buffer.from(name),
size: { width: 100, height: 100 },
display: { bounds: { x: 0, y: 0, width: 100, height: 100 } },
cursor: { x: 50, y: 50 },
size: overrides.size || { width: 100, height: 100 },
display: overrides.display || { bounds: { x: 0, y: 0, width: 100, height: 100 } },
cursor: overrides.cursor || { x: 50, y: 50 },
capturedAt: Date.now() - ageMs,
};
}
test('rapid click watcher bursts are parsed one click at a time', () => {
const service = makeService();
let clicks = 0;
service.onOsClick = () => {
clicks += 1;
};
service.processClickWatcherData([
'EVENT type 17 (RawButtonPress)',
'EVENT type 18 (RawButtonRelease)',
'EVENT type 17 (RawButtonPress)',
'EVENT type 18 (RawButtonRelease)',
].join('\n'), 'linux');
assert.equal(clicks, 2);
});
test('windows click watcher output is counted line by line', () => {
const service = makeService();
let clicks = 0;
service.onOsClick = () => {
clicks += 1;
};
service.processClickWatcherData('CLICK\r\nCLICK\r\n', 'win32');
assert.equal(clicks, 2);
});
test('a click is served instantly from the freshly buffered frame', async () => {
const service = makeService();
service.session = { guideId: 'guide-2', paused: false, count: 0, intervalSec: 0 };
@@ -81,6 +110,35 @@ test('a click is served instantly from the freshly buffered frame', async () =>
assert.equal(service.session.count, 1);
});
test('a buffered frame from a different display is ignored for click capture', async () => {
const service = makeService();
service.session = { guideId: 'guide-display', paused: false, count: 0, intervalSec: 0 };
service.frameLoopRunning = true;
service.latestFrame = makeFrame('wrong-display', 0, {
display: { bounds: { x: 0, y: 0, width: 100, height: 100 } },
});
service.nextFrame = async () => makeFrame('right-display', 0, {
display: { bounds: { x: 100, y: 0, width: 100, height: 100 } },
cursor: { x: 150, y: 10 },
});
service.shoot = async () => {
throw new Error('click capture should not fall back when a matching frame arrives');
};
const added = [];
service.store.addStep = (guideId, fields, png) => {
added.push(png.toString());
return { stepId: 'step-display' };
};
const result = await service.sessionCapture('click', { x: 150, y: 10 });
assert.equal(result.ok, true);
assert.deepEqual(added, ['right-display']);
assert.equal(service.session.count, 1);
});
test('a stale buffered frame is not reused — the click falls back to a fresh shot', async () => {
const service = makeService();
service.session = { guideId: 'guide-stale', paused: false, count: 0, intervalSec: 0 };
@@ -148,15 +206,19 @@ test('click capture marks the click-time cursor position', async () => {
};
service.session = { guideId: 'guide-4', paused: false, count: 0, intervalSec: 0 };
// No capture cache, so sessionCapture falls back to a fresh shoot().
service.captureCurrentFrame = async () => ({
mode: 'fullscreen',
png: Buffer.from('live-png'),
size: { width: 100, height: 100 },
display: { bounds: { x: 0, y: 0, width: 100, height: 100 } },
// Grab-time cursor, well outside the display — must not be used.
cursor: { x: -1, y: -1 },
capturedAt: Date.now(),
});
let seenCapturePoint = null;
service.captureCurrentFrame = async (_mode, capturePoint) => {
seenCapturePoint = capturePoint;
return {
mode: 'fullscreen',
png: Buffer.from('live-png'),
size: { width: 100, height: 100 },
display: { bounds: { x: 0, y: 0, width: 100, height: 100 } },
// Grab-time cursor, well outside the display — must not be used.
cursor: { x: -1, y: -1 },
capturedAt: Date.now(),
};
};
let added = null;
service.store.addStep = (guideId, fields, png, size) => {
@@ -168,6 +230,7 @@ test('click capture marks the click-time cursor position', async () => {
const result = await service.sessionCapture('click', { x: 50, y: 50 });
assert.equal(result.ok, true);
assert.deepEqual(seenCapturePoint, { x: 50, y: 50 });
assert.equal(added.fields.annotations.length, 1);
assert.equal(added.fields.annotations[0].type, 'oval');
});