@@ -22,6 +22,7 @@ const defaultOptions: ParsedOptions = {
2222 } ,
2323 evaluations : true ,
2424 flagChange : true ,
25+ filters : [ ] ,
2526 } ,
2627 stack : {
2728 source : {
@@ -232,3 +233,153 @@ it('logs event dropped message when maxPendingEvents is reached', () => {
232233 telemetry . captureError ( new Error ( 'Test error 4' ) ) ;
233234 expect ( mockLogger . warn ) . toHaveBeenCalledTimes ( 1 ) ;
234235} ) ;
236+
237+ it ( 'filters breadcrumbs using provided filters' , ( ) => {
238+ const options : ParsedOptions = {
239+ ...defaultOptions ,
240+ breadcrumbs : {
241+ ...defaultOptions . breadcrumbs ,
242+ click : false ,
243+ evaluations : false ,
244+ flagChange : false ,
245+ http : { instrumentFetch : false , instrumentXhr : false } ,
246+ keyboardInput : false ,
247+ filters : [
248+ // Filter to remove breadcrumbs with id:2
249+ ( breadcrumb ) => {
250+ if ( breadcrumb . type === 'custom' && breadcrumb . data ?. id === 2 ) {
251+ return undefined ;
252+ }
253+ return breadcrumb ;
254+ } ,
255+ // Filter to transform breadcrumbs with id:3
256+ ( breadcrumb ) => {
257+ if ( breadcrumb . type === 'custom' && breadcrumb . data ?. id === 3 ) {
258+ return {
259+ ...breadcrumb ,
260+ data : { id : 'filtered-3' } ,
261+ } ;
262+ }
263+ return breadcrumb ;
264+ } ,
265+ ] ,
266+ } ,
267+ } ;
268+ const telemetry = new BrowserTelemetryImpl ( options ) ;
269+
270+ telemetry . addBreadcrumb ( {
271+ type : 'custom' ,
272+ data : { id : 1 } ,
273+ timestamp : Date . now ( ) ,
274+ class : 'custom' ,
275+ level : 'info' ,
276+ } ) ;
277+
278+ telemetry . addBreadcrumb ( {
279+ type : 'custom' ,
280+ data : { id : 2 } ,
281+ timestamp : Date . now ( ) ,
282+ class : 'custom' ,
283+ level : 'info' ,
284+ } ) ;
285+
286+ telemetry . addBreadcrumb ( {
287+ type : 'custom' ,
288+ data : { id : 3 } ,
289+ timestamp : Date . now ( ) ,
290+ class : 'custom' ,
291+ level : 'info' ,
292+ } ) ;
293+
294+ const error = new Error ( 'Test error' ) ;
295+ telemetry . captureError ( error ) ;
296+ telemetry . register ( mockClient ) ;
297+
298+ expect ( mockClient . track ) . toHaveBeenCalledWith (
299+ '$ld:telemetry:error' ,
300+ expect . objectContaining ( {
301+ breadcrumbs : expect . arrayContaining ( [
302+ expect . objectContaining ( { data : { id : 1 } } ) ,
303+ expect . objectContaining ( { data : { id : 'filtered-3' } } ) ,
304+ ] ) ,
305+ } ) ,
306+ ) ;
307+
308+ // Verify breadcrumb with id:2 was filtered out
309+ expect ( mockClient . track ) . toHaveBeenCalledWith (
310+ '$ld:telemetry:error' ,
311+ expect . objectContaining ( {
312+ breadcrumbs : expect . not . arrayContaining ( [ expect . objectContaining ( { data : { id : 2 } } ) ] ) ,
313+ } ) ,
314+ ) ;
315+ } ) ;
316+
317+ it ( 'omits breadcrumb when a filter throws an exception' , ( ) => {
318+ const breadSpy = jest . fn ( ( breadcrumb ) => breadcrumb ) ;
319+ const options : ParsedOptions = {
320+ ...defaultOptions ,
321+ breadcrumbs : {
322+ ...defaultOptions . breadcrumbs ,
323+ filters : [
324+ ( ) => {
325+ throw new Error ( 'Filter error' ) ;
326+ } ,
327+ // This filter should never run
328+ breadSpy ,
329+ ] ,
330+ } ,
331+ } ;
332+ const telemetry = new BrowserTelemetryImpl ( options ) ;
333+
334+ telemetry . addBreadcrumb ( {
335+ type : 'custom' ,
336+ data : { id : 1 } ,
337+ timestamp : Date . now ( ) ,
338+ class : 'custom' ,
339+ level : 'info' ,
340+ } ) ;
341+
342+ const error = new Error ( 'Test error' ) ;
343+ telemetry . captureError ( error ) ;
344+ telemetry . register ( mockClient ) ;
345+
346+ expect ( mockClient . track ) . toHaveBeenCalledWith (
347+ '$ld:telemetry:error' ,
348+ expect . objectContaining ( {
349+ breadcrumbs : [ ] ,
350+ } ) ,
351+ ) ;
352+
353+ expect ( breadSpy ) . not . toHaveBeenCalled ( ) ;
354+ } ) ;
355+
356+ it ( 'omits breadcrumbs when a filter is not a function' , ( ) => {
357+ const options : ParsedOptions = {
358+ ...defaultOptions ,
359+ breadcrumbs : {
360+ ...defaultOptions . breadcrumbs ,
361+ // @ts -ignore
362+ filters : [ 'potato' ] ,
363+ } ,
364+ } ;
365+ const telemetry = new BrowserTelemetryImpl ( options ) ;
366+
367+ telemetry . addBreadcrumb ( {
368+ type : 'custom' ,
369+ data : { id : 1 } ,
370+ timestamp : Date . now ( ) ,
371+ class : 'custom' ,
372+ level : 'info' ,
373+ } ) ;
374+
375+ const error = new Error ( 'Test error' ) ;
376+ telemetry . captureError ( error ) ;
377+ telemetry . register ( mockClient ) ;
378+
379+ expect ( mockClient . track ) . toHaveBeenCalledWith (
380+ '$ld:telemetry:error' ,
381+ expect . objectContaining ( {
382+ breadcrumbs : [ ] ,
383+ } ) ,
384+ ) ;
385+ } ) ;
0 commit comments