mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-13 14:52:19 +00:00
test(voice): classify current-frame send and cancellation outcomes
Keep viewport and pointer-crop capture unchanged, but expose static reason codes for unavailable frames, invalidated turn captures and retained image sends. No image or user text in diagnostics.
This commit is contained in:
1 parent
8c02f5852f
commit
050f68ac03
2 files changed
+75
-2
No files matched your search
@@ -437,15 +437,24 @@ export class RealtimeViewport {
|
|||||||
const captured = await captureImage();
|
const captured = await captureImage();
|
||||||
const imageUrl =
|
const imageUrl =
|
||||||
typeof captured === 'string' ? captured : captured?.dataUrl || null;
|
typeof captured === 'string' ? captured : captured?.dataUrl || null;
|
||||||
|
if (!imageUrl) {
|
||||||
|
this.debugLog?.('viewport_context.skipped', {
|
||||||
|
reason: 'capture-unavailable',
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (
|
if (
|
||||||
!imageUrl ||
|
|
||||||
generation !== this.generation ||
|
generation !== this.generation ||
|
||||||
request !== this.captureSeq ||
|
request !== this.captureSeq ||
|
||||||
this.dc !== channel ||
|
this.dc !== channel ||
|
||||||
channel.readyState !== 'open' ||
|
channel.readyState !== 'open' ||
|
||||||
(typeof frame.valid === 'function' && !frame.valid())
|
(typeof frame.valid === 'function' && !frame.valid())
|
||||||
)
|
) {
|
||||||
|
this.debugLog?.('viewport_context.skipped', {
|
||||||
|
reason: 'capture-invalidated',
|
||||||
|
});
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Keep at most one viewport screenshot in context. Images are the single
|
// Keep at most one viewport screenshot in context. Images are the single
|
||||||
// most expensive item (re-billed every turn they linger), so we proactively
|
// most expensive item (re-billed every turn they linger), so we proactively
|
||||||
@@ -506,6 +515,9 @@ export class RealtimeViewport {
|
|||||||
cameraKey: this.readCameraKey(),
|
cameraKey: this.readCameraKey(),
|
||||||
}
|
}
|
||||||
: null;
|
: null;
|
||||||
|
this.debugLog?.('viewport_context.result', {
|
||||||
|
reason: sent ? 'sent' : 'data-channel-send-failed',
|
||||||
|
});
|
||||||
return sent;
|
return sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -179,3 +179,64 @@ test('closed channel never captures pointer or full viewport', async () => {
|
|||||||
);
|
);
|
||||||
assert.equal(await viewport.sendVisualContextIfUseful(localContext()), false);
|
assert.equal(await viewport.sendVisualContextIfUseful(localContext()), false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('capture failures and invalidated turns are reason-coded without sending', async () => {
|
||||||
|
const channel = { readyState: 'open' };
|
||||||
|
const diagnostics = [];
|
||||||
|
const viewport = new RealtimeViewport({
|
||||||
|
readChannel: () => channel,
|
||||||
|
operations: {
|
||||||
|
sendRealtimeEvent: () => {
|
||||||
|
throw new Error('should not send unavailable image');
|
||||||
|
},
|
||||||
|
debugLog: (event, detail) => diagnostics.push({ event, detail }),
|
||||||
|
},
|
||||||
|
capture: async () => null,
|
||||||
|
});
|
||||||
|
assert.equal(await viewport.sendVisualContextIfUseful(localContext()), false);
|
||||||
|
assert.ok(
|
||||||
|
diagnostics.some(
|
||||||
|
(item) =>
|
||||||
|
item.event === 'viewport_context.skipped' &&
|
||||||
|
item.detail.reason === 'capture-unavailable',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
let release;
|
||||||
|
viewport.capture = () =>
|
||||||
|
new Promise((resolve) => {
|
||||||
|
release = resolve;
|
||||||
|
});
|
||||||
|
const pending = viewport.sendVisualContextIfUseful(localContext());
|
||||||
|
viewport.reset();
|
||||||
|
release('data:image/jpeg;base64,AA==');
|
||||||
|
assert.equal(await pending, false);
|
||||||
|
assert.ok(
|
||||||
|
diagnostics.some(
|
||||||
|
(item) =>
|
||||||
|
item.event === 'viewport_context.skipped' &&
|
||||||
|
item.detail.reason === 'capture-invalidated',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('successful retained send is logged without recording image contents', async () => {
|
||||||
|
const channel = { readyState: 'open' };
|
||||||
|
const diagnostics = [];
|
||||||
|
const viewport = new RealtimeViewport({
|
||||||
|
readChannel: () => channel,
|
||||||
|
readCameraKey: () => 'camera:fixture',
|
||||||
|
operations: {
|
||||||
|
sendRealtimeEvent: () => true,
|
||||||
|
debugLog: (event, detail) => diagnostics.push({ event, detail }),
|
||||||
|
},
|
||||||
|
capture: async () => 'data:image/jpeg;base64,AA==',
|
||||||
|
});
|
||||||
|
assert.equal(await viewport.sendVisualContextIfUseful(localContext()), true);
|
||||||
|
assert.ok(diagnostics.some((item) =>
|
||||||
|
item.event === 'viewport_context.result' && item.detail.reason === 'sent'
|
||||||
|
));
|
||||||
|
assert.equal(
|
||||||
|
JSON.stringify(diagnostics).includes('data:image/jpeg'),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
});
|
||||||
Reference in new issue
Block a user