@@ -173,3 +173,128 @@ sentryTest(
173
173
expect ( content2 . breadcrumbs ) . toEqual ( expect . arrayContaining ( [ expectedClickBreadcrumb ] ) ) ;
174
174
} ,
175
175
) ;
176
+
177
+ sentryTest (
178
+ '[buffer-mode] manually start buffer mode and capture buffer, but do not continue as session' ,
179
+ async ( { getLocalTestPath, page, browserName } ) => {
180
+ // This was sometimes flaky on firefox/webkit, so skipping for now
181
+ if ( shouldSkipReplayTest ( ) || [ 'firefox' , 'webkit' ] . includes ( browserName ) ) {
182
+ sentryTest . skip ( ) ;
183
+ }
184
+
185
+ let callsToSentry = 0 ;
186
+ let errorEventId : string | undefined ;
187
+ const reqPromise0 = waitForReplayRequest ( page , 0 ) ;
188
+ const reqErrorPromise = waitForErrorRequest ( page ) ;
189
+
190
+ await page . route ( 'https://dsn.ingest.sentry.io/**/*' , route => {
191
+ const event = envelopeRequestParser ( route . request ( ) ) ;
192
+ // error events have no type field
193
+ if ( event && ! event . type && event . event_id ) {
194
+ errorEventId = event . event_id ;
195
+ }
196
+ // We only want to count errors & replays here
197
+ if ( event && ( ! event . type || isReplayEvent ( event ) ) ) {
198
+ callsToSentry ++ ;
199
+ }
200
+
201
+ return route . fulfill ( {
202
+ status : 200 ,
203
+ contentType : 'application/json' ,
204
+ body : JSON . stringify ( { id : 'test-id' } ) ,
205
+ } ) ;
206
+ } ) ;
207
+
208
+ const url = await getLocalTestPath ( { testDir : __dirname } ) ;
209
+
210
+ await page . goto ( url ) ;
211
+ await page . click ( '#go-background' ) ;
212
+ await page . click ( '#error' ) ;
213
+ await new Promise ( resolve => setTimeout ( resolve , 1000 ) ) ;
214
+
215
+ // error, no replays
216
+ expect ( callsToSentry ) . toEqual ( 1 ) ;
217
+ await reqErrorPromise ;
218
+
219
+ expect (
220
+ await page . evaluate ( ( ) => {
221
+ const replayIntegration = ( window as unknown as Window & { Replay : { _replay : ReplayContainer } } ) . Replay ;
222
+ const replay = replayIntegration . _replay ;
223
+ return replay . isEnabled ( ) ;
224
+ } ) ,
225
+ ) . toBe ( false ) ;
226
+
227
+ // Start buffering and assert that it is enabled
228
+ expect (
229
+ await page . evaluate ( ( ) => {
230
+ const replayIntegration = ( window as unknown as Window & { Replay : InstanceType < typeof Replay > } ) . Replay ;
231
+ // @ts -ignore private
232
+ const replay = replayIntegration . _replay ;
233
+ replayIntegration . startBuffering ( ) ;
234
+ return replay . isEnabled ( ) ;
235
+ } ) ,
236
+ ) . toBe ( true ) ;
237
+
238
+ await page . click ( '#log' ) ;
239
+ await page . click ( '#go-background' ) ;
240
+ await page . click ( '#error2' ) ;
241
+ await new Promise ( resolve => setTimeout ( resolve , 1000 ) ) ;
242
+
243
+ // 2 errors
244
+ expect ( callsToSentry ) . toEqual ( 2 ) ;
245
+
246
+ await page . evaluate ( async ( ) => {
247
+ const replayIntegration = ( window as unknown as Window & { Replay : Replay } ) . Replay ;
248
+ await replayIntegration . flush ( { continueRecording : false } ) ;
249
+ } ) ;
250
+
251
+ const req0 = await reqPromise0 ;
252
+
253
+ // 2 errors, 1 flush
254
+ expect ( callsToSentry ) . toEqual ( 3 ) ;
255
+
256
+ await page . click ( '#log' ) ;
257
+ await page . click ( '#go-background' ) ;
258
+
259
+ // Has stopped recording, should make no more calls to Sentry
260
+ expect ( callsToSentry ) . toEqual ( 3 ) ;
261
+
262
+ const event0 = getReplayEvent ( req0 ) ;
263
+ const content0 = getReplayRecordingContent ( req0 ) ;
264
+
265
+ expect ( event0 ) . toEqual (
266
+ getExpectedReplayEvent ( {
267
+ contexts : { replay : { error_sample_rate : 0 , session_sample_rate : 0 } } ,
268
+ error_ids : [ errorEventId ! ] ,
269
+ replay_type : 'buffer' ,
270
+ } ) ,
271
+ ) ;
272
+
273
+ // The first event should have both, full and incremental snapshots,
274
+ // as we recorded and kept all events in the buffer
275
+ expect ( content0 . fullSnapshots ) . toHaveLength ( 1 ) ;
276
+ // We don't know how many incremental snapshots we'll have (also browser-dependent),
277
+ // but we know that we have at least 5
278
+ expect ( content0 . incrementalSnapshots . length ) . toBeGreaterThan ( 5 ) ;
279
+ // We want to make sure that the event that triggered the error was recorded.
280
+ expect ( content0 . breadcrumbs ) . toEqual (
281
+ expect . arrayContaining ( [
282
+ {
283
+ ...expectedClickBreadcrumb ,
284
+ message : 'body > button#error2' ,
285
+ data : {
286
+ nodeId : expect . any ( Number ) ,
287
+ node : {
288
+ attributes : {
289
+ id : 'error2' ,
290
+ } ,
291
+ id : expect . any ( Number ) ,
292
+ tagName : 'button' ,
293
+ textContent : '******* *****' ,
294
+ } ,
295
+ } ,
296
+ } ,
297
+ ] ) ,
298
+ ) ;
299
+ } ,
300
+ ) ;
0 commit comments