@@ -178,6 +178,93 @@ sentryTest('captures JSON response body', async ({ getLocalTestPath, page, brows
178178 ] ) ;
179179} ) ;
180180
181+ sentryTest ( 'captures JSON response body when responseType=json' , async ( { getLocalTestPath, page, browserName } ) => {
182+ // These are a bit flaky on non-chromium browsers
183+ if ( shouldSkipReplayTest ( ) || browserName !== 'chromium' ) {
184+ sentryTest . skip ( ) ;
185+ }
186+
187+ await page . route ( '**/foo' , route => {
188+ return route . fulfill ( {
189+ status : 200 ,
190+ body : JSON . stringify ( { res : 'this' } ) ,
191+ headers : {
192+ 'Content-Length' : '' ,
193+ } ,
194+ } ) ;
195+ } ) ;
196+
197+ await page . route ( 'https://dsn.ingest.sentry.io/**/*' , route => {
198+ return route . fulfill ( {
199+ status : 200 ,
200+ contentType : 'application/json' ,
201+ body : JSON . stringify ( { id : 'test-id' } ) ,
202+ } ) ;
203+ } ) ;
204+
205+ const requestPromise = waitForErrorRequest ( page ) ;
206+ const replayRequestPromise1 = waitForReplayRequest ( page , 0 ) ;
207+
208+ const url = await getLocalTestPath ( { testDir : __dirname } ) ;
209+ await page . goto ( url ) ;
210+
211+ void page . evaluate ( ( ) => {
212+ /* eslint-disable */
213+ const xhr = new XMLHttpRequest ( ) ;
214+
215+ xhr . open ( 'POST' , 'http://localhost:7654/foo' ) ;
216+ // Setting this to json ensures that xhr.response returns a POJO
217+ xhr . responseType = 'json' ;
218+ xhr . send ( ) ;
219+
220+ xhr . addEventListener ( 'readystatechange' , function ( ) {
221+ if ( xhr . readyState === 4 ) {
222+ // @ts -expect-error Sentry is a global
223+ setTimeout ( ( ) => Sentry . captureException ( 'test error' , 0 ) ) ;
224+ }
225+ } ) ;
226+ /* eslint-enable */
227+ } ) ;
228+
229+ const request = await requestPromise ;
230+ const eventData = envelopeRequestParser ( request ) ;
231+
232+ expect ( eventData . exception ?. values ) . toHaveLength ( 1 ) ;
233+
234+ expect ( eventData ?. breadcrumbs ?. length ) . toBe ( 1 ) ;
235+ expect ( eventData ! . breadcrumbs ! [ 0 ] ) . toEqual ( {
236+ timestamp : expect . any ( Number ) ,
237+ category : 'xhr' ,
238+ type : 'http' ,
239+ data : {
240+ method : 'POST' ,
241+ response_body_size : 14 ,
242+ status_code : 200 ,
243+ url : 'http://localhost:7654/foo' ,
244+ } ,
245+ } ) ;
246+
247+ const replayReq1 = await replayRequestPromise1 ;
248+ const { performanceSpans : performanceSpans1 } = getCustomRecordingEvents ( replayReq1 ) ;
249+ expect ( performanceSpans1 . filter ( span => span . op === 'resource.xhr' ) ) . toEqual ( [
250+ {
251+ data : {
252+ method : 'POST' ,
253+ statusCode : 200 ,
254+ response : {
255+ size : 14 ,
256+ headers : { } ,
257+ body : { res : 'this' } ,
258+ } ,
259+ } ,
260+ description : 'http://localhost:7654/foo' ,
261+ endTimestamp : expect . any ( Number ) ,
262+ op : 'resource.xhr' ,
263+ startTimestamp : expect . any ( Number ) ,
264+ } ,
265+ ] ) ;
266+ } ) ;
267+
181268sentryTest ( 'captures non-text response body' , async ( { getLocalTestPath, page, browserName } ) => {
182269 // These are a bit flaky on non-chromium browsers
183270 if ( shouldSkipReplayTest ( ) || browserName !== 'chromium' ) {
0 commit comments