11import { checkAjaxEvents , checkJsErrors , checkMetrics , checkGenericEvents , checkPVT , checkRumBody , checkRumQuery , checkSessionTrace , checkSpa } from '../util/basic-checks'
2- import { testAjaxEventsRequest , testAjaxTimeSlicesRequest , testBlobTraceRequest , testCustomMetricsRequest , testErrorsRequest , testEventsRequest , testInsRequest , testInteractionEventsRequest , testLogsRequest , testMetricsRequest , testRumRequest , testTimingEventsRequest } from '../../tools/testing-server/utils/expect-tests'
2+ import { testAjaxEventsRequest , testAjaxTimeSlicesRequest , testBlobTraceRequest , testCustomMetricsRequest , testErrorsRequest , testEventsRequest , testInsRequest , testInteractionEventsRequest , testLogsRequest , testMetricsRequest , testMFEErrorsRequest , testMFEInsRequest , testRumRequest , testTimingEventsRequest } from '../../tools/testing-server/utils/expect-tests'
33import { rumFlags } from '../../tools/testing-server/constants'
44import { LOGGING_MODE } from '../../src/features/logging/constants'
55
@@ -8,6 +8,161 @@ describe('newrelic api', () => {
88 await browser . destroyAgentSession ( )
99 } )
1010
11+ describe ( 'registered-entity' , ( ) => {
12+ const featureFlags = [
13+ [ ] ,
14+ [ 'register' ] ,
15+ [ 'register' , 'register.jserrors' ] ,
16+ [ 'register' , 'register.generic_events' ] ,
17+ [ 'register' , 'register.jserrors' , 'register.generic_events' ] ,
18+ [ 'register.jserrors' , 'register.generic_events' ] ,
19+ [ 'register.jserrors' ] ,
20+ [ 'register.generic_events' ]
21+ ]
22+ featureFlags . forEach ( ( testSet ) => {
23+ it ( `RegisteredEntity -- ${ testSet . join ( ' | ' ) || 'no flags' } ` , async ( ) => {
24+ const [ rumCapture , mfeErrorsCapture , mfeInsightsCapture , regularErrorsCapture , regularInsightsCapture , logsCapture ] = await browser . testHandle . createNetworkCaptures ( 'bamServer' , [
25+ { test : testRumRequest } ,
26+ { test : testMFEErrorsRequest } ,
27+ { test : testMFEInsRequest } ,
28+ { test : testErrorsRequest } ,
29+ { test : testInsRequest } ,
30+ { test : testLogsRequest }
31+ ] )
32+ await browser . url ( await browser . testHandle . assetURL ( 'instrumented.html' , { init : { feature_flags : testSet } } ) )
33+
34+ await browser . execute ( function ( ) {
35+ window . agent1 = newrelic . register ( {
36+ id : 1 ,
37+ name : 'agent1'
38+ } )
39+ window . agent2 = newrelic . register ( {
40+ id : 2 ,
41+ name : 'agent2'
42+ } )
43+
44+ // each payload in this test is decorated with data that matches its appId for ease of testing
45+ window . newrelic . setCustomAttribute ( 'customAttr' , '42' ) // container agent
46+ window . agent1 . setCustomAttribute ( 'customAttr' , '1' ) // micro agent (agent1)
47+ window . agent2 . setCustomAttribute ( 'customAttr' , '2' ) // micro agent (agent2)
48+
49+ // each payload in this test is decorated with data that matches its appId for ease of testing
50+ window . newrelic . noticeError ( '42' )
51+ window . agent1 . noticeError ( '1' )
52+ window . agent2 . noticeError ( '2' )
53+
54+ // each payload in this test is decorated with data that matches its appId for ease of testing
55+ window . newrelic . addPageAction ( '42' , { val : 42 } )
56+ window . agent1 . addPageAction ( '1' , { val : 1 } )
57+ window . agent2 . addPageAction ( '2' , { val : 2 } )
58+
59+ // each payload in this test is decorated with data that matches its appId for ease of testing
60+ window . newrelic . log ( '42' )
61+ window . agent1 . log ( '1' , { level : 'error' } )
62+ window . agent2 . log ( '2' , { level : 'error' } )
63+ } )
64+ const [ rumHarvests , errorsHarvests , insightsHarvests , logsHarvest ] = await Promise . all ( [
65+ rumCapture . waitForResult ( { totalCount : 1 , timeout : 10000 } ) ,
66+ ( testSet . includes ( 'register.jserrors' ) ? mfeErrorsCapture : regularErrorsCapture ) . waitForResult ( { totalCount : 1 , timeout : 10000 } ) ,
67+ ( testSet . includes ( 'register.generic_events' ) ? mfeInsightsCapture : regularInsightsCapture ) . waitForResult ( { totalCount : 1 , timeout : 10000 } ) ,
68+ logsCapture . waitForResult ( { totalCount : 1 , timeout : 10000 } )
69+ ] )
70+
71+ const containerAgentEntityGuid = await browser . execute ( function ( ) {
72+ return Object . values ( newrelic . initializedAgents ) [ 0 ] . runtime . appMetadata . agents [ 0 ] . entityGuid
73+ } )
74+
75+ // these props will get set to true once a test has matched it
76+ // if it gets tried again, the test will fail, since these should all
77+ // only have one distinct matching payload
78+ const tests = {
79+ 42 : { rum : false , err : false , pa : false , log : false } , // container agent defaults to appId 42
80+ 1 : { err : false , pa : false , log : false } , // agent1 instance
81+ 2 : { err : false , pa : false , log : false } // agent2 instance
82+ }
83+
84+ expect ( rumHarvests ) . toHaveLength ( 1 )
85+ expect ( errorsHarvests . length ) . toBeGreaterThanOrEqual ( 1 )
86+ expect ( insightsHarvests . length ) . toBeGreaterThanOrEqual ( 1 )
87+ expect ( logsHarvest . length ) . toBeGreaterThanOrEqual ( 1 )
88+
89+ // each type of test should check that:
90+ // each payload exists once per appId
91+ // each payload should have internal attributes matching it to the right appId
92+ rumHarvests . forEach ( ( { request : { query, body } } ) => {
93+ expect ( ranOnce ( query . a , 'rum' ) ) . toEqual ( true )
94+ } )
95+
96+ errorsHarvests . forEach ( ( { request : { query, body } } ) => {
97+ const data = body . err
98+ data . forEach ( ( err , idx ) => {
99+ const id = err . custom [ 'mfe.id' ] || query . a // MFEs use mfe.id, regular agents use appId
100+ if ( Number ( id ) !== 42 && testSet . includes ( 'register.jserrors' ) ) {
101+ expect ( err . custom [ 'mfe.name' ] ) . toEqual ( 'agent' + id )
102+ expect ( err . custom . eventSource ) . toEqual ( 'MicroFrontendBrowserAgent' )
103+ expect ( err . custom [ 'parent.id' ] ) . toEqual ( containerAgentEntityGuid )
104+ }
105+ countRuns ( id , 'err' )
106+ if ( testSet . includes ( 'register.jserrors' ) ) {
107+ expect ( ranOnce ( id , 'err' ) ) . toEqual ( true )
108+ expect ( Number ( id ) ) . toEqual ( Number ( err . params . message ) )
109+ } else {
110+ expect ( tests [ id ] . err ) . toEqual ( idx + 1 ) // each error gets lumped together under the same id without the feature flags
111+ expect ( Number ( id ) ) . toEqual ( 42 )
112+ }
113+ } )
114+ } )
115+
116+ insightsHarvests . forEach ( ( { request : { query, body } } ) => {
117+ const data = body . ins
118+ data . forEach ( ( ins , idx ) => {
119+ if ( ins . eventType === 'PageAction' ) {
120+ const id = ins [ 'mfe.id' ] || query . a // MFEs use mfe.id, regular agents use appId
121+ if ( Number ( id ) !== 42 && testSet . includes ( 'register.generic_events' ) ) {
122+ expect ( ins [ 'mfe.name' ] ) . toEqual ( 'agent' + id )
123+ expect ( ins . eventSource ) . toEqual ( 'MicroFrontendBrowserAgent' )
124+ expect ( ins [ 'parent.id' ] ) . toEqual ( containerAgentEntityGuid )
125+ }
126+ countRuns ( id , 'pa' )
127+ if ( testSet . includes ( 'register.generic_events' ) ) {
128+ expect ( ranOnce ( id , 'pa' ) ) . toEqual ( true )
129+ expect ( Number ( id ) ) . toEqual ( Number ( ins . val ) )
130+ } else {
131+ expect ( tests [ id ] . pa ) . toEqual ( idx + 1 ) // each error gets lumped together under the same id without the feature flags
132+ expect ( Number ( id ) ) . toEqual ( 42 )
133+ }
134+ }
135+ } )
136+ } )
137+
138+ logsHarvest . forEach ( ( { request : { query, body } } ) => {
139+ const data = JSON . parse ( body ) [ 0 ]
140+ data . logs . forEach ( log => {
141+ const id = log . attributes [ 'mfe.id' ] || 42 // MFEs use mfe.id, regular agents supply entity guid so just force it to 42 here if mfe id is not present
142+ if ( Number ( id ) !== 42 && testSet . includes ( 'register' ) ) {
143+ expect ( log . attributes [ 'mfe.name' ] ) . toEqual ( 'agent' + id )
144+ expect ( log . attributes . eventSource ) . toEqual ( 'MicroFrontendBrowserAgent' )
145+ expect ( log . attributes [ 'parent.id' ] ) . toEqual ( containerAgentEntityGuid )
146+ }
147+ expect ( ranOnce ( id , 'log' ) ) . toEqual ( true )
148+ expect ( Number ( id ) ) . toEqual ( Number ( log . message ) )
149+ } )
150+ } )
151+
152+ function ranOnce ( appId , type ) {
153+ if ( tests [ appId ] [ type ] > 1 ) return false
154+ countRuns ( appId , type )
155+ return true
156+ }
157+
158+ function countRuns ( appId , type ) {
159+ tests [ appId ] [ type ] ??= 0
160+ tests [ appId ] [ type ] ++
161+ }
162+ } )
163+ } )
164+ } )
165+
11166 it ( 'should expose api methods' , async ( ) => {
12167 await browser . url ( await browser . testHandle . assetURL ( 'api/local-storage-disallowed.html' ) ) // Setup expects before loading the page
13168 . then ( ( ) => browser . waitForAgentLoad ( ) )
0 commit comments