@@ -148,6 +148,90 @@ describe('Integration | errorSampleRate', () => {
148148 } ) ;
149149 } ) ;
150150
151+ it ( 'loads an old session with a previousSessionId set and can send buffered replay' , async ( ) => {
152+ vi . mock ( '../../src/session/fetchSession' , ( ) => ( {
153+ fetchSession : ( ) => ( {
154+ id : 'newreplayid' ,
155+ started : BASE_TIMESTAMP ,
156+ lastActivity : BASE_TIMESTAMP ,
157+ segmentId : 0 ,
158+ sampled : 'buffer' ,
159+ previousSessionId : 'previoussessionid' ,
160+ } ) ,
161+ } ) ) ;
162+
163+ const ADVANCED_TIME = 86400000 ;
164+ const optionsEvent = createOptionsEvent ( replay ) ;
165+
166+ expect ( replay . session . started ) . toBe ( BASE_TIMESTAMP ) ;
167+
168+ // advance time to make sure replay duration is invalid
169+ vi . advanceTimersByTime ( ADVANCED_TIME ) ;
170+
171+ // full snapshot should update session start time
172+ mockRecord . takeFullSnapshot ( true ) ;
173+ expect ( replay . session . started ) . toBe ( BASE_TIMESTAMP + ADVANCED_TIME ) ;
174+ expect ( replay . recordingMode ) . toBe ( 'buffer' ) ;
175+
176+ // advance so we can flush
177+ vi . advanceTimersByTime ( DEFAULT_FLUSH_MIN_DELAY ) ;
178+
179+ captureException ( new Error ( 'testing' ) ) ;
180+ await vi . advanceTimersToNextTimerAsync ( ) ;
181+
182+ // Converts to session mode
183+ expect ( replay . recordingMode ) . toBe ( 'session' ) ;
184+ expect ( replay ) . toHaveLastSentReplay ( {
185+ recordingPayloadHeader : { segment_id : 0 } ,
186+ replayEventPayload : expect . objectContaining ( {
187+ replay_type : 'buffer' ,
188+ } ) ,
189+ recordingData : JSON . stringify ( [
190+ { data : { isCheckout : true } , timestamp : BASE_TIMESTAMP + ADVANCED_TIME , type : 2 } ,
191+ { ...optionsEvent , timestamp : BASE_TIMESTAMP + ADVANCED_TIME } ,
192+ ] ) ,
193+ } ) ;
194+
195+ // capture next event
196+ domHandler ( {
197+ name : 'click' ,
198+ event : new Event ( 'click' ) ,
199+ } ) ;
200+
201+ vi . advanceTimersByTime ( DEFAULT_FLUSH_MIN_DELAY ) ;
202+ await vi . advanceTimersToNextTimerAsync ( ) ;
203+
204+ expect ( replay ) . toHaveLastSentReplay ( {
205+ recordingPayloadHeader : { segment_id : 1 } ,
206+ replayEventPayload : expect . objectContaining ( {
207+ // We don't change replay_type as it starts in buffer mode and that's
208+ // what we're interested in, even though recordingMode changes to
209+ // 'session'
210+ replay_type : 'buffer' ,
211+ } ) ,
212+ recordingData : JSON . stringify ( [
213+ // There's a new checkout because we convert to session mode
214+ { data : { isCheckout : true } , timestamp : BASE_TIMESTAMP + ADVANCED_TIME + DEFAULT_FLUSH_MIN_DELAY , type : 2 } ,
215+ {
216+ type : 5 ,
217+ timestamp : BASE_TIMESTAMP + ADVANCED_TIME + DEFAULT_FLUSH_MIN_DELAY ,
218+ data : {
219+ tag : 'breadcrumb' ,
220+ payload : {
221+ timestamp : ( BASE_TIMESTAMP + ADVANCED_TIME + DEFAULT_FLUSH_MIN_DELAY ) / 1000 ,
222+ type : 'default' ,
223+ category : 'ui.click' ,
224+ message : '<unknown>' ,
225+ data : { } ,
226+ } ,
227+ } ,
228+ } ,
229+ ] ) ,
230+ } ) ;
231+ vi . unmock ( '../../src/session/fetchSession' ) ;
232+ await waitForFlush ( ) ;
233+ } ) ;
234+
151235 it ( 'manually flushes replay and does not continue to record' , async ( ) => {
152236 const TEST_EVENT = getTestEventIncremental ( { timestamp : BASE_TIMESTAMP } ) ;
153237 mockRecord . _emitter ( TEST_EVENT ) ;
0 commit comments