@@ -10,7 +10,7 @@ import {
1010import { interceptRequests , registerCleanupTask } from '@datadog/browser-core/test'
1111import { appendElement } from '../../../test'
1212import type { RumInitConfiguration } from './configuration'
13- import type { RumRemoteConfiguration } from './remoteConfiguration'
13+ import type { RumRemoteConfiguration , RemoteConfigurationMetrics } from './remoteConfiguration'
1414import { applyRemoteConfiguration , buildEndpoint , fetchRemoteConfiguration } from './remoteConfiguration'
1515
1616const DEFAULT_INIT_CONFIGURATION : RumInitConfiguration = {
@@ -99,11 +99,15 @@ describe('remoteConfiguration', () => {
9999 } )
100100
101101 describe ( 'applyRemoteConfiguration' , ( ) => {
102+ const COOKIE_NAME = 'unit_rc'
103+ const root = window as any
104+
102105 let displaySpy : jasmine . Spy
103106 let supportedContextManagers : {
104107 user : ReturnType < typeof createContextManager >
105108 context : ReturnType < typeof createContextManager >
106109 }
110+ let metrics : RemoteConfigurationMetrics
107111
108112 function expectAppliedRemoteConfigurationToBe (
109113 actual : Partial < RumRemoteConfiguration > ,
@@ -114,7 +118,7 @@ describe('remoteConfiguration', () => {
114118 ...actual ,
115119 }
116120 expect (
117- applyRemoteConfiguration ( DEFAULT_INIT_CONFIGURATION , rumRemoteConfiguration , supportedContextManagers )
121+ applyRemoteConfiguration ( DEFAULT_INIT_CONFIGURATION , rumRemoteConfiguration , supportedContextManagers , metrics )
118122 ) . toEqual ( {
119123 ...DEFAULT_INIT_CONFIGURATION ,
120124 applicationId : 'yyy' ,
@@ -125,6 +129,7 @@ describe('remoteConfiguration', () => {
125129 beforeEach ( ( ) => {
126130 displaySpy = spyOn ( display , 'error' )
127131 supportedContextManagers = { user : createContextManager ( ) , context : createContextManager ( ) }
132+ metrics = { fetch : { } }
128133 } )
129134
130135 it ( 'should override the initConfiguration options with the ones from the remote configuration' , ( ) => {
@@ -151,7 +156,7 @@ describe('remoteConfiguration', () => {
151156 defaultPrivacyLevel : DefaultPrivacyLevel . ALLOW ,
152157 }
153158 expect (
154- applyRemoteConfiguration ( DEFAULT_INIT_CONFIGURATION , rumRemoteConfiguration , supportedContextManagers )
159+ applyRemoteConfiguration ( DEFAULT_INIT_CONFIGURATION , rumRemoteConfiguration , supportedContextManagers , metrics )
155160 ) . toEqual ( {
156161 applicationId : 'yyy' ,
157162 clientToken : 'xxx' ,
@@ -194,22 +199,22 @@ describe('remoteConfiguration', () => {
194199 } )
195200
196201 describe ( 'cookie strategy' , ( ) => {
197- const COOKIE_NAME = 'unit_rc'
198-
199202 it ( 'should resolve a configuration value from a cookie' , ( ) => {
200203 setCookie ( COOKIE_NAME , 'my-version' , ONE_MINUTE )
201204 registerCleanupTask ( ( ) => deleteCookie ( COOKIE_NAME ) )
202205 expectAppliedRemoteConfigurationToBe (
203206 { version : { rcSerializedType : 'dynamic' , strategy : 'cookie' , name : COOKIE_NAME } } ,
204207 { version : 'my-version' }
205208 )
209+ expect ( metrics . cookie ) . toEqual ( { success : 1 } )
206210 } )
207211
208212 it ( 'should resolve to undefined if the cookie is missing' , ( ) => {
209213 expectAppliedRemoteConfigurationToBe (
210214 { version : { rcSerializedType : 'dynamic' , strategy : 'cookie' , name : COOKIE_NAME } } ,
211215 { version : undefined }
212216 )
217+ expect ( metrics . cookie ) . toEqual ( { missing : 1 } )
213218 } )
214219 } )
215220
@@ -226,6 +231,7 @@ describe('remoteConfiguration', () => {
226231 { version : { rcSerializedType : 'dynamic' , strategy : 'dom' , selector : '#version1' } } ,
227232 { version : 'version-123' }
228233 )
234+ expect ( metrics . dom ) . toEqual ( { success : 1 } )
229235 } )
230236
231237 it ( 'should resolve a configuration value from an element text content and an extractor' , ( ) => {
@@ -255,13 +261,15 @@ describe('remoteConfiguration', () => {
255261 { version : undefined }
256262 )
257263 expect ( displaySpy ) . toHaveBeenCalledWith ( "Invalid selector in the remote configuration: ''" )
264+ expect ( metrics . dom ) . toEqual ( { failure : 1 } )
258265 } )
259266
260267 it ( 'should resolve to undefined if the element is missing' , ( ) => {
261268 expectAppliedRemoteConfigurationToBe (
262269 { version : { rcSerializedType : 'dynamic' , strategy : 'dom' , selector : '#missing' } } ,
263270 { version : undefined }
264271 )
272+ expect ( metrics . dom ) . toEqual ( { missing : 1 } )
265273 } )
266274
267275 it ( 'should resolve a configuration value from an element attribute' , ( ) => {
@@ -278,6 +286,7 @@ describe('remoteConfiguration', () => {
278286 { version : { rcSerializedType : 'dynamic' , strategy : 'dom' , selector : '#version2' , attribute : 'missing' } } ,
279287 { version : undefined }
280288 )
289+ expect ( metrics . dom ) . toEqual ( { missing : 1 } )
281290 } )
282291
283292 it ( 'should resolve to undefined if trying to access a password input value attribute' , ( ) => {
@@ -286,12 +295,11 @@ describe('remoteConfiguration', () => {
286295 { version : { rcSerializedType : 'dynamic' , strategy : 'dom' , selector : '#pwd' , attribute : 'value' } } ,
287296 { version : undefined }
288297 )
298+ expect ( displaySpy ) . toHaveBeenCalledWith ( "Forbidden element selected by the remote configuration: '#pwd'" )
289299 } )
290300 } )
291301
292302 describe ( 'js strategy' , ( ) => {
293- const root = window as any
294-
295303 it ( 'should resolve a value from a variable content' , ( ) => {
296304 root . foo = 'bar'
297305 registerCleanupTask ( ( ) => {
@@ -303,6 +311,7 @@ describe('remoteConfiguration', () => {
303311 } ,
304312 { version : 'bar' }
305313 )
314+ expect ( metrics . js ) . toEqual ( { success : 1 } )
306315 } )
307316
308317 it ( 'should resolve a value from an object property' , ( ) => {
@@ -401,6 +410,7 @@ describe('remoteConfiguration', () => {
401410 { version : undefined }
402411 )
403412 expect ( displaySpy ) . toHaveBeenCalledWith ( "Invalid JSON path in the remote configuration: '.'" )
413+ expect ( metrics . js ) . toEqual ( { failure : 1 } )
404414 } )
405415
406416 it ( 'should resolve to undefined and display an error if the variable access throws' , ( ) => {
@@ -419,6 +429,7 @@ describe('remoteConfiguration', () => {
419429 { version : undefined }
420430 )
421431 expect ( displaySpy ) . toHaveBeenCalledWith ( "Error accessing: 'foo.bar'" , new Error ( 'foo' ) )
432+ expect ( metrics . js ) . toEqual ( { failure : 1 } )
422433 } )
423434
424435 it ( 'should resolve to undefined if the variable does not exist' , ( ) => {
@@ -428,6 +439,7 @@ describe('remoteConfiguration', () => {
428439 } ,
429440 { version : undefined }
430441 )
442+ expect ( metrics . js ) . toEqual ( { missing : 1 } )
431443 } )
432444
433445 it ( 'should resolve to undefined if the property does not exist' , ( ) => {
@@ -442,6 +454,7 @@ describe('remoteConfiguration', () => {
442454 } ,
443455 { version : undefined }
444456 )
457+ expect ( metrics . js ) . toEqual ( { missing : 1 } )
445458 } )
446459
447460 it ( 'should resolve to undefined if the array index does not exist' , ( ) => {
@@ -456,12 +469,11 @@ describe('remoteConfiguration', () => {
456469 } ,
457470 { version : undefined }
458471 )
472+ expect ( metrics . js ) . toEqual ( { missing : 1 } )
459473 } )
460474 } )
461475
462476 describe ( 'with extractor' , ( ) => {
463- const COOKIE_NAME = 'unit_rc'
464-
465477 beforeEach ( ( ) => {
466478 setCookie ( COOKIE_NAME , 'my-version-123' , ONE_MINUTE )
467479 } )
@@ -529,8 +541,6 @@ describe('remoteConfiguration', () => {
529541 } )
530542
531543 describe ( 'supported contexts' , ( ) => {
532- const COOKIE_NAME = 'unit_rc'
533-
534544 beforeEach ( ( ) => {
535545 setCookie ( COOKIE_NAME , 'first.second' , ONE_MINUTE )
536546 } )
@@ -592,6 +602,63 @@ describe('remoteConfiguration', () => {
592602 } )
593603 } )
594604 } )
605+
606+ describe ( 'metrics' , ( ) => {
607+ it ( 'should report resolution stats' , ( ) => {
608+ setCookie ( COOKIE_NAME , 'my-version' , ONE_MINUTE )
609+ root . foo = '123'
610+ registerCleanupTask ( ( ) => {
611+ deleteCookie ( COOKIE_NAME )
612+ delete root . foo
613+ } )
614+
615+ expectAppliedRemoteConfigurationToBe (
616+ {
617+ context : [
618+ {
619+ key : 'missing-cookie' ,
620+ value : {
621+ rcSerializedType : 'dynamic' ,
622+ strategy : 'cookie' ,
623+ name : 'missing-cookie' ,
624+ } ,
625+ } ,
626+ {
627+ key : 'existing-cookie' ,
628+ value : {
629+ rcSerializedType : 'dynamic' ,
630+ strategy : 'cookie' ,
631+ name : COOKIE_NAME ,
632+ } ,
633+ } ,
634+ {
635+ key : 'existing-cookie2' ,
636+ value : {
637+ rcSerializedType : 'dynamic' ,
638+ strategy : 'cookie' ,
639+ name : COOKIE_NAME ,
640+ } ,
641+ } ,
642+ {
643+ key : 'existing-js' ,
644+ value : {
645+ rcSerializedType : 'dynamic' ,
646+ strategy : 'js' ,
647+ path : 'foo' ,
648+ } ,
649+ } ,
650+ ] ,
651+ } ,
652+ { }
653+ )
654+ expect ( metrics ) . toEqual (
655+ jasmine . objectContaining ( {
656+ cookie : { success : 2 , missing : 1 } ,
657+ js : { success : 1 } ,
658+ } )
659+ )
660+ } )
661+ } )
595662 } )
596663
597664 describe ( 'buildEndpoint' , ( ) => {
0 commit comments