11import { beforeEach , describe , expect , it , vi } from "vitest" ;
2- import { RECORD_FRAME_PORT } from "../recording/frame-bridge" ;
2+ import { RECORD_FRAME_PORT , RECORD_FRAME_QUERY } from "../recording/frame-bridge" ;
33import { RecordFrameCoordinator } from "../recording/frame-coordinator" ;
44
55class ListenerSet < T extends ( ...args : never [ ] ) => unknown > {
@@ -46,6 +46,98 @@ describe("RecordFrameCoordinator", () => {
4646 } ) ;
4747 } ) ;
4848
49+ it ( "answers child-document queries for the initial tab before it is armed" , ( ) => {
50+ const coordinator = new RecordFrameCoordinator ( {
51+ getAllFrames : async ( ) => [ ] ,
52+ sendToDocument : async ( ) => ( { ok : true } ) ,
53+ } ) ;
54+ coordinator . attach ( ) ;
55+ coordinator . begin ( "rec-1" , 10 , 3 ) ;
56+
57+ const query = ( tabId : number ) => {
58+ let response : unknown ;
59+ for ( const listener of onMessage . listeners ) {
60+ listener (
61+ { type : RECORD_FRAME_QUERY } ,
62+ {
63+ tab : { id : tabId } ,
64+ frameId : 7 ,
65+ documentId : "child-document" ,
66+ } as chrome . runtime . MessageSender ,
67+ ( value ) => {
68+ response = value ;
69+ } ,
70+ ) ;
71+ }
72+ return response ;
73+ } ;
74+
75+ expect ( query ( 3 ) ) . toEqual ( { active : true , requestId : "rec-1" , startedAtMs : 10 } ) ;
76+ expect ( query ( 4 ) ) . toEqual ( { active : false } ) ;
77+ } ) ;
78+
79+ it ( "starts a child Document that appears after the initial frame snapshot" , async ( ) => {
80+ let notifyFrameNavigation :
81+ | ( ( frame : {
82+ tabId : number ;
83+ frameId : number ;
84+ documentId ?: string ;
85+ lifecycle : "committed" | "completed" ;
86+ } ) => void )
87+ | undefined ;
88+ const sendToDocument = vi . fn ( async ( ) => ( { ok : true } ) ) ;
89+ const coordinator = new RecordFrameCoordinator ( {
90+ getAllFrames : async ( ) => [ { frameId : 0 , documentId : "top-document" } ] ,
91+ sendToDocument,
92+ subscribeFrameNavigation ( listener ) {
93+ notifyFrameNavigation = listener ;
94+ return ( ) => { } ;
95+ } ,
96+ } ) ;
97+ coordinator . attach ( ) ;
98+ const onDocumentReady = vi . fn ( ) ;
99+ coordinator . begin ( "rec-1" , 10 , 3 , onDocumentReady ) ;
100+ await coordinator . armTab ( "rec-1" , 3 ) ;
101+ sendToDocument . mockClear ( ) ;
102+
103+ notifyFrameNavigation ?.( {
104+ tabId : 3 ,
105+ frameId : 7 ,
106+ documentId : "late-child" ,
107+ lifecycle : "completed" ,
108+ } ) ;
109+ await vi . waitFor ( ( ) => {
110+ expect ( sendToDocument ) . toHaveBeenCalledWith (
111+ 3 ,
112+ { type : "bsk-record-frame-start" , requestId : "rec-1" , startedAtMs : 10 } ,
113+ { documentId : "late-child" } ,
114+ ) ;
115+ } ) ;
116+ expect ( onDocumentReady ) . not . toHaveBeenCalled ( ) ;
117+
118+ const child = fakePort ( {
119+ tab : { id : 3 } ,
120+ frameId : 7 ,
121+ documentId : "late-child" ,
122+ } as chrome . runtime . MessageSender ) ;
123+ for ( const listener of onConnect . listeners ) listener ( child . port ) ;
124+ child . receive ( { type : "ready" , requestId : "rec-1" , producerId : "producer-1" } ) ;
125+ notifyFrameNavigation ?.( {
126+ tabId : 3 ,
127+ frameId : 7 ,
128+ documentId : "late-child" ,
129+ lifecycle : "completed" ,
130+ } ) ;
131+ await vi . waitFor ( ( ) => {
132+ expect ( onDocumentReady ) . toHaveBeenCalledWith ( {
133+ tabId : 3 ,
134+ documentId : "late-child" ,
135+ browserFrameId : 7 ,
136+ producerId : "producer-1" ,
137+ } ) ;
138+ } ) ;
139+ } ) ;
140+
49141 it ( "binds a producer to its sender Document and keeps final steps valid while stopping" , async ( ) => {
50142 const sendToDocument = vi . fn ( async ( ) => ( { ok : true } ) ) ;
51143 const coordinator = new RecordFrameCoordinator ( {
@@ -56,7 +148,7 @@ describe("RecordFrameCoordinator", () => {
56148 sendToDocument,
57149 } ) ;
58150 coordinator . attach ( ) ;
59- coordinator . begin ( "rec-1" , 10 ) ;
151+ coordinator . begin ( "rec-1" , 10 , 3 ) ;
60152 await expect ( coordinator . armTab ( "rec-1" , 3 ) ) . resolves . toBe ( true ) ;
61153
62154 const sender = {
@@ -100,7 +192,7 @@ describe("RecordFrameCoordinator", () => {
100192 sendToDocument : async ( ) => ( { ok : true } ) ,
101193 } ) ;
102194 coordinator . attach ( ) ;
103- coordinator . begin ( "rec-1" , 10 ) ;
195+ coordinator . begin ( "rec-1" , 10 , 3 ) ;
104196 await coordinator . armTab ( "rec-1" , 3 ) ;
105197 const sender = {
106198 tab : { id : 3 } ,
0 commit comments