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

This commit is contained in:
Iisyourdad
2026-06-11 13:02:37 -05:00
parent 3d80c86abf
commit 298d7728b8
2 changed files with 194 additions and 48 deletions
+40 -14
View File
@@ -63,31 +63,51 @@ function makeFrame(name, ageMs = 0, overrides = {}) {
test('rapid click watcher bursts are parsed one click at a time', () => {
const service = makeService();
let clicks = 0;
service.onOsClick = () => {
clicks += 1;
const clicks = [];
service.normalizeClickPoint = (point) => point;
service.onOsClick = (clickPos) => {
clicks.push(clickPos);
};
service.processClickWatcherData([
'EVENT type 17 (RawButtonPress)',
'root: 10/20',
'EVENT type 18 (RawButtonRelease)',
'EVENT type 17 (RawButtonPress)',
'root: 30/40',
'EVENT type 18 (RawButtonRelease)',
].join('\n'), 'linux');
assert.equal(clicks, 2);
assert.deepEqual(clicks, [
{ x: 10, y: 20 },
{ x: 30, y: 40 },
]);
});
test('windows click watcher output is counted line by line', () => {
test('windows click watcher output is buffered and parsed with coordinates', () => {
const service = makeService();
let clicks = 0;
service.onOsClick = () => {
clicks += 1;
const clicks = [];
service.normalizeClickPoint = (point) => point;
service.onOsClick = (clickPos) => {
clicks.push(clickPos);
};
service.processClickWatcherData('CLICK\r\nCLICK\r\n', 'win32');
service.processClickWatcherData('CL', 'win32');
service.processClickWatcherData('ICK 100 200\r\nCLICK 300 400\r\n', 'win32');
assert.equal(clicks, 2);
assert.deepEqual(clicks, [
{ x: 100, y: 200 },
{ x: 300, y: 400 },
]);
});
test('the windows click watcher script installs a low-level mouse hook', () => {
const service = makeService();
const script = service.windowsClickWatcherScript();
assert.match(script, /WH_MOUSE_LL/);
assert.match(script, /WM_LBUTTONDOWN/);
assert.match(script, /CLICK \{0\} \{1\}/);
});
test('a click is served instantly from the freshly buffered frame', async () => {
@@ -157,7 +177,7 @@ test('a stale buffered frame is not reused — the click falls back to a fresh s
assert.equal(shootCalled, true, 'a stale buffered frame must not be reused');
});
test('an idle click capture does not wait for the next frame loop tick', async () => {
test('a running frame loop waits for the next buffered frame when the cache is empty', async () => {
const service = makeService();
service.session = { guideId: 'guide-idle', paused: false, count: 0, intervalSec: 0 };
service.frameLoopRunning = true;
@@ -166,7 +186,7 @@ test('an idle click capture does not wait for the next frame loop tick', async (
let nextFrameCalled = false;
service.nextFrame = async () => {
nextFrameCalled = true;
throw new Error('idle clicks must not wait for a new frame');
return makeFrame('loop-frame');
};
let shootCalled = false;
@@ -174,12 +194,18 @@ test('an idle click capture does not wait for the next frame loop tick', async (
shootCalled = true;
return { ok: true, step: { stepId: 'idle-step' } };
};
const added = [];
service.store.addStep = (guideId, fields, png) => {
added.push(png.toString());
return { stepId: 'idle-step' };
};
const result = await service.sessionCapture('click', { x: 1, y: 1 });
assert.equal(result.ok, true);
assert.equal(shootCalled, true);
assert.equal(nextFrameCalled, false);
assert.equal(shootCalled, false);
assert.equal(nextFrameCalled, true);
assert.deepEqual(added, ['loop-frame']);
});
test('clicks during an in-flight grab wait for the frame instead of being dropped', async () => {