@@ -2,16 +2,29 @@ import { test } from 'vitest';
22import assert from 'node:assert/strict' ;
33import { attachRefs } from '@agent-device/kernel/snapshot' ;
44import type { RawSnapshotNode , SnapshotNode } from '@agent-device/kernel/snapshot' ;
5+ import type { TargetAnnotationV1 } from '@agent-device/contracts/replay' ;
56import { computeTargetEvidence } from './target-evidence.ts' ;
67import {
78 parseTargetAnnotationV1Payload ,
8- serializeTargetAnnotationV1 ,
9+ formatTargetAnnotationLines ,
10+ serializeRawTargetAnnotationV1 ,
911 utf8ByteLength ,
1012 TARGET_ANNOTATION_MAX_ANCESTRY ,
1113 TARGET_ANNOTATION_MAX_FIELD_BYTES ,
1214 TARGET_ANNOTATION_MAX_PAYLOAD_BYTES ,
1315} from '@agent-device/ad-script' ;
1416
17+ function serializeTargetAnnotationV1 ( evidence : TargetAnnotationV1 ) : string {
18+ const [ line ] = formatTargetAnnotationLines ( {
19+ ts : 0 ,
20+ command : 'click' ,
21+ positionals : [ ] ,
22+ flags : { } ,
23+ targetEvidence : evidence ,
24+ } ) ;
25+ return line ! . slice ( '# agent-device:target-v1 ' . length ) ;
26+ }
27+
1528function toSnapshotNodes ( raw : RawSnapshotNode [ ] ) : SnapshotNode [ ] {
1629 return attachRefs ( raw ) ;
1730}
@@ -252,7 +265,7 @@ test('computeTargetEvidence: escape-heavy fields degrade until the unverifiable
252265 utf8ByteLength ( json ) <= TARGET_ANNOTATION_MAX_PAYLOAD_BYTES ,
253266 `payload is ${ utf8ByteLength ( json ) } bytes` ,
254267 ) ;
255- assert . deepEqual ( parseTargetAnnotationV1Payload ( json ) , evidence ) ;
268+ assert . equal ( parseTargetAnnotationV1Payload ( json ) . verification , 'unverifiable' ) ;
256269} ) ;
257270
258271// #4333: the downgrade drops optional fields in a fixed order and stops at the first payload that
@@ -290,8 +303,13 @@ test('computeTargetEvidence: an oversized payload drops rect, scrollRegion, ance
290303 const stops = new Set < number > ( ) ;
291304 for ( let labelLength = 1 ; labelLength <= TARGET_ANNOTATION_MAX_FIELD_BYTES ; labelLength += 1 ) {
292305 const nodes = build ( labelLength ) ;
293- const evidence = computeTargetEvidence ( { node : nodes . at ( - 1 ) ! , preActionNodes : nodes } ) ;
294- assert . ok ( evidence ) ;
306+ const candidate = computeTargetEvidence ( { node : nodes . at ( - 1 ) ! , preActionNodes : nodes } ) ;
307+ assert . ok ( candidate ) ;
308+ assert . deepEqual ( candidate . rect , rect ) ;
309+ assert . deepEqual ( candidate . scrollRegion , SCROLL_CONTAINER ) ;
310+ assert . equal ( candidate . label , '\u0001' . repeat ( labelLength ) ) ;
311+ assert . deepEqual ( candidate . ancestry [ 0 ] , SCROLL_CONTAINER ) ;
312+ const evidence = parseTargetAnnotationV1Payload ( serializeTargetAnnotationV1 ( candidate ) ) ;
295313 const firstKept = OVERSIZED_DROP_ORDER . findIndex ( ( field ) => isPresent ( evidence , field ) ) ;
296314 const droppedCount = firstKept === - 1 ? OVERSIZED_DROP_ORDER . length : firstKept ;
297315 for ( const field of OVERSIZED_DROP_ORDER . slice ( droppedCount ) ) {
@@ -313,7 +331,8 @@ test('computeTargetEvidence: an oversized payload drops rect, scrollRegion, ance
313331 [ lastDropped ] : undropped [ lastDropped ] ,
314332 } ) ;
315333 assert . ok (
316- utf8ByteLength ( serializeTargetAnnotationV1 ( restored ) ) > TARGET_ANNOTATION_MAX_PAYLOAD_BYTES ,
334+ utf8ByteLength ( serializeRawTargetAnnotationV1 ( restored ) ) >
335+ TARGET_ANNOTATION_MAX_PAYLOAD_BYTES ,
317336 `${ lastDropped } dropped at length ${ labelLength } although the payload already fit` ,
318337 ) ;
319338 }
0 commit comments