@newrelic/browser-agent 1.242.0 → 1.243.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/CHANGELOG.md +1465 -0
  2. package/dist/cjs/common/constants/env.cdn.js +1 -1
  3. package/dist/cjs/common/constants/env.npm.js +1 -1
  4. package/dist/cjs/common/session/session-entity.js +20 -2
  5. package/dist/cjs/common/wrap/wrap-function.js +1 -1
  6. package/dist/cjs/features/ajax/aggregate/index.js +1 -1
  7. package/dist/cjs/features/session_replay/aggregate/index.js +84 -54
  8. package/dist/cjs/features/utils/feature-base.js +1 -2
  9. package/dist/cjs/loaders/api/api.js +2 -2
  10. package/dist/cjs/loaders/api/apiAsync.js +0 -37
  11. package/dist/cjs/loaders/configure/configure.js +1 -1
  12. package/dist/cjs/loaders/configure/public-path.js +6 -3
  13. package/dist/esm/common/constants/env.cdn.js +1 -1
  14. package/dist/esm/common/constants/env.npm.js +1 -1
  15. package/dist/esm/common/session/session-entity.js +18 -1
  16. package/dist/esm/common/wrap/wrap-function.js +1 -1
  17. package/dist/esm/features/ajax/aggregate/index.js +1 -1
  18. package/dist/esm/features/session_replay/aggregate/index.js +83 -54
  19. package/dist/esm/features/utils/feature-base.js +1 -2
  20. package/dist/esm/loaders/api/api.js +2 -2
  21. package/dist/esm/loaders/api/apiAsync.js +1 -36
  22. package/dist/esm/loaders/configure/configure.js +1 -1
  23. package/dist/esm/loaders/configure/public-path.js +6 -3
  24. package/dist/types/common/session/session-entity.d.ts +5 -0
  25. package/dist/types/common/session/session-entity.d.ts.map +1 -1
  26. package/dist/types/features/session_replay/aggregate/index.d.ts +11 -14
  27. package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
  28. package/dist/types/features/utils/feature-base.d.ts.map +1 -1
  29. package/dist/types/loaders/api/api.d.ts.map +1 -1
  30. package/dist/types/loaders/api/apiAsync.d.ts.map +1 -1
  31. package/dist/types/loaders/configure/public-path.d.ts +1 -1
  32. package/dist/types/loaders/configure/public-path.d.ts.map +1 -1
  33. package/package.json +2 -2
  34. package/src/common/session/session-entity.js +20 -1
  35. package/src/common/wrap/wrap-function.js +1 -1
  36. package/src/features/ajax/aggregate/index.js +2 -2
  37. package/src/features/session_replay/aggregate/index.js +81 -37
  38. package/src/features/utils/feature-base.js +1 -2
  39. package/src/loaders/api/api.js +1 -2
  40. package/src/loaders/api/apiAsync.js +1 -39
  41. package/src/loaders/configure/configure.js +1 -1
  42. package/src/loaders/configure/public-path.js +6 -3
  43. package/src/common/aggregate/aggregator.test.js +0 -107
  44. package/src/common/config/state/configurable.test.js +0 -73
  45. package/src/common/config/state/info.test.js +0 -31
  46. package/src/common/config/state/init.test.js +0 -68
  47. package/src/common/config/state/loader-config.test.js +0 -21
  48. package/src/common/config/state/runtime.test.js +0 -21
  49. package/src/common/constants/env.cdn.test.js +0 -7
  50. package/src/common/constants/env.npm.test.js +0 -7
  51. package/src/common/constants/env.test.js +0 -7
  52. package/src/common/constants/runtime.test.js +0 -176
  53. package/src/common/deny-list/deny-list.test.js +0 -104
  54. package/src/common/dom/query-selector.test.js +0 -24
  55. package/src/common/drain/drain.test.js +0 -74
  56. package/src/common/event-emitter/contextual-ee.component-test.js +0 -293
  57. package/src/common/event-emitter/handle.test.js +0 -56
  58. package/src/common/event-emitter/register-handler.test.js +0 -61
  59. package/src/common/harvest/harvest-scheduler.test.js +0 -492
  60. package/src/common/harvest/harvest.test.js +0 -813
  61. package/src/common/ids/id.test.js +0 -92
  62. package/src/common/ids/unique-id.test.js +0 -58
  63. package/src/common/session/session-entity.component-test.js +0 -346
  64. package/src/common/storage/local-storage.test.js +0 -17
  65. package/src/common/timer/interaction-timer.component-test.js +0 -212
  66. package/src/common/timer/timer.test.js +0 -99
  67. package/src/common/timing/nav-timing.test.js +0 -161
  68. package/src/common/url/canonicalize-url.test.js +0 -45
  69. package/src/common/url/clean-url.test.js +0 -25
  70. package/src/common/url/encode.test.js +0 -81
  71. package/src/common/url/location.test.js +0 -15
  72. package/src/common/url/parse-url.test.js +0 -110
  73. package/src/common/url/protocol.test.js +0 -17
  74. package/src/common/util/console.test.js +0 -34
  75. package/src/common/util/data-size.test.js +0 -56
  76. package/src/common/util/feature-flags.test.js +0 -94
  77. package/src/common/util/get-or-set.test.js +0 -58
  78. package/src/common/util/invoke.test.js +0 -65
  79. package/src/common/util/map-own.test.js +0 -52
  80. package/src/common/util/obfuscate.component-test.js +0 -173
  81. package/src/common/util/stringify.test.js +0 -49
  82. package/src/common/util/submit-data.test.js +0 -183
  83. package/src/common/util/traverse.test.js +0 -50
  84. package/src/common/vitals/cumulative-layout-shift.test.js +0 -71
  85. package/src/common/vitals/first-contentful-paint.test.js +0 -124
  86. package/src/common/vitals/first-input-delay.test.js +0 -88
  87. package/src/common/vitals/first-paint.test.js +0 -127
  88. package/src/common/vitals/interaction-to-next-paint.test.js +0 -74
  89. package/src/common/vitals/largest-contentful-paint.test.js +0 -94
  90. package/src/common/vitals/long-task.test.js +0 -122
  91. package/src/common/vitals/time-to-first-byte.test.js +0 -147
  92. package/src/common/vitals/vital-metric.test.js +0 -171
  93. package/src/common/wrap/wrap-promise.component-test.js +0 -110
  94. package/src/features/ajax/instrument/distributed-tracing.test.js +0 -375
  95. package/src/features/jserrors/aggregate/canonical-function-name.test.js +0 -13
  96. package/src/features/jserrors/aggregate/compute-stack-trace.test.js +0 -414
  97. package/src/features/jserrors/aggregate/format-stack-trace.test.js +0 -39
  98. package/src/features/jserrors/aggregate/string-hash-code.test.js +0 -12
  99. package/src/features/metrics/aggregate/framework-detection.test.js +0 -332
  100. package/src/features/page_view_timing/aggregate/index.component-test.js +0 -86
  101. package/src/features/session_replay/aggregate/index.component-test.js +0 -317
  102. package/src/features/spa/aggregate/interaction-node.test.js +0 -17
  103. package/src/features/utils/agent-session.test.js +0 -194
  104. package/src/features/utils/aggregate-base.test.js +0 -123
  105. package/src/features/utils/feature-base.test.js +0 -45
  106. package/src/features/utils/handler-cache.test.js +0 -72
  107. package/src/features/utils/instrument-base.test.js +0 -216
  108. package/src/features/utils/lazy-feature-loader.test.js +0 -37
  109. package/src/loaders/api/api.component-test.js +0 -45
  110. package/src/loaders/api/api.test.js +0 -85
  111. package/src/loaders/api/apiAsync.test.js +0 -17
@@ -1,72 +0,0 @@
1
- import { HandlerCache } from './handler-cache'
2
-
3
- jest.useFakeTimers()
4
-
5
- test('should immediately invoke handler when decision has already been made and is true', () => {
6
- const handlerCache = new HandlerCache()
7
- handlerCache.decide(true)
8
-
9
- const handler = jest.fn()
10
- handlerCache.settle(handler)
11
-
12
- expect(handler).toHaveBeenCalled()
13
- })
14
-
15
- test('should not invoke handler when decision has already been made and is false', () => {
16
- const handlerCache = new HandlerCache()
17
- handlerCache.decide(false)
18
-
19
- const handler = jest.fn()
20
- handlerCache.settle(handler)
21
-
22
- expect(handler).not.toHaveBeenCalled()
23
- })
24
-
25
- test('should cache the handler until a decision is made', () => {
26
- const handlerCache = new HandlerCache()
27
-
28
- const handler = jest.fn()
29
- handlerCache.settle(handler)
30
- expect(handler).not.toHaveBeenCalled()
31
-
32
- handlerCache.decide(true)
33
- expect(handler).toHaveBeenCalled()
34
- })
35
-
36
- test('should not invoke handler when decision times out', () => {
37
- const handlerCache = new HandlerCache()
38
- jest.advanceTimersByTime(10000)
39
-
40
- const handler = jest.fn()
41
- handlerCache.settle(handler)
42
-
43
- expect(handler).not.toHaveBeenCalled()
44
- })
45
-
46
- test('should clear the timeout when a decision is made', () => {
47
- jest.spyOn(global, 'setTimeout')
48
- jest.spyOn(global, 'clearTimeout')
49
-
50
- const handlerCache = new HandlerCache()
51
-
52
- const handler = jest.fn()
53
- handlerCache.settle(handler)
54
- handlerCache.decide(true)
55
-
56
- const timeout = jest.mocked(global.setTimeout).mock.results[0].value
57
- expect(global.clearTimeout).toHaveBeenCalledWith(timeout)
58
- })
59
-
60
- test('should not allow another decision after a permanent one', () => {
61
- jest.spyOn(global, 'clearTimeout')
62
-
63
- const handlerCache = new HandlerCache()
64
-
65
- const handler = jest.fn()
66
- handlerCache.settle(handler)
67
- handlerCache.permanentlyDecide(false)
68
- handlerCache.decide(true)
69
-
70
- expect(global.clearTimeout).toHaveBeenCalledTimes(1)
71
- expect(handler).not.toHaveBeenCalled()
72
- })
@@ -1,216 +0,0 @@
1
- import { faker } from '@faker-js/faker'
2
- import { InstrumentBase } from './instrument-base'
3
- import { FeatureBase } from './feature-base'
4
- import { drain, registerDrain } from '../../common/drain/drain'
5
- import { onWindowLoad } from '../../common/window/load'
6
- import { lazyFeatureLoader } from './lazy-feature-loader'
7
- import { getConfigurationValue } from '../../common/config/config'
8
- import { setupAgentSession } from './agent-session'
9
- import { warn } from '../../common/util/console'
10
- import * as globalScopeModule from '../../common/constants/runtime'
11
- import { FEATURE_NAMES } from '../../loaders/features/features'
12
-
13
- jest.enableAutomock()
14
- jest.unmock('./instrument-base')
15
- jest.unmock('../../loaders/features/features')
16
- jest.mock('../../common/drain/drain', () => ({
17
- __esModule: true,
18
- drain: jest.fn(),
19
- registerDrain: jest.fn()
20
- }))
21
- jest.mock('../../common/window/load', () => ({
22
- __esModule: true,
23
- onWindowLoad: jest.fn()
24
- }))
25
- jest.mock('../../common/constants/runtime', () => ({
26
- __esModule: true,
27
- isBrowserScope: undefined,
28
- isWorkerScope: undefined
29
- }))
30
- jest.mock('../../common/config/config', () => ({
31
- __esModule: true,
32
- getConfigurationValue: jest.fn()
33
- }))
34
- jest.mock('../../common/config/config', () => ({
35
- __esModule: true,
36
- getConfigurationValue: jest.fn().mockReturnValue({}),
37
- originals: {
38
- MO: jest.fn()
39
- }
40
- }))
41
- jest.mock('./feature-base', () => ({
42
- __esModule: true,
43
- FeatureBase: jest.fn(function (...args) {
44
- this.agentIdentifier = args[0]
45
- this.aggregator = args[1]
46
- this.featureName = args[2]
47
- })
48
- }))
49
- jest.mock('./agent-session', () => ({
50
- __esModule: true,
51
- setupAgentSession: jest.fn()
52
- }))
53
-
54
- let agentIdentifier
55
- let aggregator
56
- let featureName
57
- let mockAggregate
58
-
59
- beforeEach(() => {
60
- jest.replaceProperty(globalScopeModule, 'isBrowserScope', true)
61
- jest.replaceProperty(globalScopeModule, 'isWorkerScope', false)
62
-
63
- agentIdentifier = faker.datatype.uuid()
64
- aggregator = {}
65
- featureName = faker.datatype.uuid()
66
-
67
- mockAggregate = jest.fn()
68
- jest.mocked(lazyFeatureLoader).mockResolvedValue({ Aggregate: mockAggregate })
69
- })
70
-
71
- test('should construct a new instrument', () => {
72
- const instrument = new InstrumentBase(agentIdentifier, aggregator, featureName)
73
-
74
- expect(FeatureBase).toHaveBeenCalledWith(agentIdentifier, aggregator, featureName)
75
- expect(instrument.featAggregate).toBeUndefined()
76
- expect(instrument.auto).toEqual(true)
77
- expect(instrument.abortHandler).toBeUndefined()
78
- expect(registerDrain).toHaveBeenCalledWith(agentIdentifier, featureName)
79
- })
80
-
81
- test('should not immediately drain', () => {
82
- new InstrumentBase(agentIdentifier, aggregator, featureName, false)
83
-
84
- expect(registerDrain).not.toHaveBeenCalled()
85
- })
86
-
87
- test('should import aggregator on window load', async () => {
88
- const instrument = new InstrumentBase(agentIdentifier, aggregator, featureName)
89
- const aggregateArgs = { [faker.datatype.uuid()]: faker.lorem.sentence() }
90
- instrument.importAggregator(aggregateArgs)
91
-
92
- const windowLoadCallback = jest.mocked(onWindowLoad).mock.calls[0][0]
93
- await windowLoadCallback()
94
-
95
- expect(onWindowLoad).toHaveBeenCalledWith(expect.any(Function), true)
96
- expect(lazyFeatureLoader).toHaveBeenCalledWith(featureName, 'aggregate')
97
- expect(mockAggregate).toHaveBeenCalledWith(agentIdentifier, aggregator, aggregateArgs)
98
- })
99
-
100
- test('should immediately import aggregator in worker scope', async () => {
101
- jest.replaceProperty(globalScopeModule, 'isBrowserScope', false)
102
- jest.replaceProperty(globalScopeModule, 'isWorkerScope', true)
103
-
104
- const instrument = new InstrumentBase(agentIdentifier, aggregator, featureName)
105
- const aggregateArgs = { [faker.datatype.uuid()]: faker.lorem.sentence() }
106
- instrument.importAggregator(aggregateArgs)
107
-
108
- // In worker scope, we cannot wait on importLater method
109
- await new Promise(process.nextTick)
110
-
111
- expect(onWindowLoad).not.toHaveBeenCalled()
112
- expect(lazyFeatureLoader).toHaveBeenCalledWith(featureName, 'aggregate')
113
- expect(mockAggregate).toHaveBeenCalledWith(agentIdentifier, aggregator, aggregateArgs)
114
- })
115
-
116
- test('should import the session manager and replay aggregate for new session', async () => {
117
- jest.mocked(getConfigurationValue).mockReturnValue(true)
118
- jest.mocked(setupAgentSession).mockReturnValue({
119
- isNew: true
120
- })
121
-
122
- const instrument = new InstrumentBase(agentIdentifier, aggregator, FEATURE_NAMES.sessionReplay)
123
- const aggregateArgs = { [faker.datatype.uuid()]: faker.lorem.sentence() }
124
- instrument.importAggregator(aggregateArgs)
125
-
126
- const windowLoadCallback = jest.mocked(onWindowLoad).mock.calls[0][0]
127
- await windowLoadCallback()
128
-
129
- expect(getConfigurationValue).toHaveBeenCalledWith(agentIdentifier, 'privacy.cookies_enabled')
130
- expect(setupAgentSession).toHaveBeenCalledWith(agentIdentifier)
131
- expect(lazyFeatureLoader).toHaveBeenCalledWith(FEATURE_NAMES.sessionReplay, 'aggregate')
132
- expect(mockAggregate).toHaveBeenCalledWith(agentIdentifier, aggregator, aggregateArgs)
133
- })
134
-
135
- test('should import the session manager and replay aggregate when a recording is active', async () => {
136
- jest.mocked(getConfigurationValue).mockReturnValue(true)
137
- jest.mocked(setupAgentSession).mockReturnValue({
138
- isNew: false,
139
- state: {
140
- sessionReplay: 1
141
- }
142
- })
143
-
144
- const instrument = new InstrumentBase(agentIdentifier, aggregator, FEATURE_NAMES.sessionReplay)
145
- const aggregateArgs = { [faker.datatype.uuid()]: faker.lorem.sentence() }
146
- instrument.importAggregator(aggregateArgs)
147
-
148
- const windowLoadCallback = jest.mocked(onWindowLoad).mock.calls[0][0]
149
- await windowLoadCallback()
150
-
151
- expect(getConfigurationValue).toHaveBeenCalledWith(agentIdentifier, 'privacy.cookies_enabled')
152
- expect(setupAgentSession).toHaveBeenCalledWith(agentIdentifier)
153
- expect(lazyFeatureLoader).toHaveBeenCalledWith(FEATURE_NAMES.sessionReplay, 'aggregate')
154
- expect(mockAggregate).toHaveBeenCalledWith(agentIdentifier, aggregator, aggregateArgs)
155
- })
156
-
157
- test('should not import session aggregate when session is not new and a recording is not active', async () => {
158
- jest.mocked(getConfigurationValue).mockReturnValue(true)
159
- jest.mocked(setupAgentSession).mockReturnValue({
160
- isNew: false,
161
- state: {
162
- sessionReplay: 0
163
- }
164
- })
165
-
166
- const instrument = new InstrumentBase(agentIdentifier, aggregator, FEATURE_NAMES.sessionReplay)
167
- const aggregateArgs = { [faker.datatype.uuid()]: faker.lorem.sentence() }
168
- instrument.importAggregator(aggregateArgs)
169
-
170
- const windowLoadCallback = jest.mocked(onWindowLoad).mock.calls[0][0]
171
- await windowLoadCallback()
172
-
173
- expect(getConfigurationValue).toHaveBeenCalledWith(agentIdentifier, 'privacy.cookies_enabled')
174
- expect(setupAgentSession).toHaveBeenCalledWith(agentIdentifier)
175
- expect(drain).toHaveBeenCalledWith(agentIdentifier, FEATURE_NAMES.sessionReplay)
176
- expect(lazyFeatureLoader).not.toHaveBeenCalled()
177
- expect(mockAggregate).not.toHaveBeenCalled()
178
- })
179
-
180
- test('feature still imports by default even when setupAgentSession throws an error', async () => {
181
- jest.mocked(getConfigurationValue).mockReturnValue(true)
182
- jest.mocked(setupAgentSession).mockImplementation(() => { throw new Error(faker.lorem.sentence()) })
183
-
184
- const instrument = new InstrumentBase(agentIdentifier, aggregator, featureName)
185
- const aggregateArgs = { [faker.datatype.uuid()]: faker.lorem.sentence() }
186
- instrument.abortHandler = jest.fn()
187
- instrument.importAggregator(aggregateArgs)
188
-
189
- const windowLoadCallback = jest.mocked(onWindowLoad).mock.calls[0][0]
190
- await windowLoadCallback()
191
-
192
- expect(onWindowLoad).toHaveBeenCalledWith(expect.any(Function), true)
193
- expect(instrument.abortHandler).not.toHaveBeenCalled()
194
- expect(warn).toHaveBeenCalledWith(expect.stringContaining('A problem occurred when starting up session manager'), expect.any(Error))
195
- expect(lazyFeatureLoader).toHaveBeenCalled()
196
- expect(mockAggregate).toHaveBeenCalled()
197
- await expect(instrument.onAggregateImported).resolves.toBe(true)
198
- })
199
-
200
- test('no uncaught async exception is thrown when an import fails', async () => {
201
- jest.mocked(lazyFeatureLoader).mockRejectedValue(new Error('ChunkLoadError')) // () => { throw new Error('ChunkLoadError: loading chunk xxx failed.') })
202
- const mockOnError = jest.fn()
203
- global.onerror = mockOnError
204
-
205
- const instrument = new InstrumentBase(agentIdentifier, aggregator, featureName)
206
- instrument.abortHandler = jest.fn()
207
- instrument.importAggregator()
208
-
209
- const windowLoadCallback = jest.mocked(onWindowLoad).mock.calls[0][0]
210
- await windowLoadCallback()
211
-
212
- expect(warn).toHaveBeenNthCalledWith(2, expect.stringContaining(`Downloading and initializing ${featureName} failed`), expect.any(Error))
213
- expect(instrument.abortHandler).toHaveBeenCalled()
214
- await expect(instrument.onAggregateImported).resolves.toBe(false)
215
- expect(mockOnError).not.toHaveBeenCalled()
216
- })
@@ -1,37 +0,0 @@
1
- import { faker } from '@faker-js/faker'
2
- import { FEATURE_NAMES } from '../../loaders/features/features'
3
- import { lazyFeatureLoader } from './lazy-feature-loader'
4
-
5
- // Use enableAutomock to make it easier to mock all the things that get imported by the aggregators
6
- jest.enableAutomock()
7
- // Unmock the file under test and the constants file
8
- jest.unmock('../../loaders/features/features')
9
- jest.unmock('./lazy-feature-loader')
10
-
11
- test.each(Object.keys(FEATURE_NAMES))('should import the aggregate for feature %s', async (key) => {
12
- const featureName = FEATURE_NAMES[key]
13
- const randomId = faker.datatype.uuid()
14
-
15
- jest.setMock(`../${featureName}/aggregate`, {
16
- id: randomId,
17
- featureName
18
- })
19
-
20
- const result = await lazyFeatureLoader(featureName, 'aggregate')
21
-
22
- expect(result.id).toEqual(randomId)
23
- expect(result.featureName).toEqual(featureName)
24
- })
25
-
26
- test('should throw an error when the featureName is not supported', async () => {
27
- const featureName = faker.datatype.uuid()
28
-
29
- expect(() => lazyFeatureLoader(featureName, 'aggregate')).toThrow()
30
- })
31
-
32
- test('should return undefined when the featurePart is not supported', async () => {
33
- const featureName = faker.datatype.uuid()
34
- const featurePart = faker.datatype.uuid()
35
-
36
- expect(lazyFeatureLoader(featureName, featurePart)).toBeUndefined()
37
- })
@@ -1,45 +0,0 @@
1
- import { setAPI } from './api'
2
- import { setInfo, getInfo, setConfiguration } from '../../common/config/config'
3
-
4
- setInfo('abcd', { licenseKey: '1234', applicationID: '1234' })
5
- setConfiguration('abcd', {})
6
- let apiInterface
7
- beforeEach(() => {
8
- console.warn = jest.fn()
9
- apiInterface = setAPI('abcd', true)
10
- })
11
-
12
- afterEach(() => {
13
- jest.restoreAllMocks()
14
- })
15
-
16
- describe('api', () => {
17
- describe('setApplicationVersion', () => {
18
- test('setApplicationVersion sets and unsets ja with valid values', () => {
19
- apiInterface.setApplicationVersion('1.2.3')
20
- expect(getInfo('abcd').jsAttributes).toMatchObject({ 'application.version': '1.2.3' })
21
-
22
- apiInterface.setApplicationVersion(null)
23
- expect(getInfo('abcd').jsAttributes).toMatchObject({ })
24
- })
25
-
26
- test('setApplicationVersion warns if invalid data is supplied', () => {
27
- apiInterface.setApplicationVersion(1)
28
- expect(console.warn).toHaveBeenCalledWith('New Relic: Failed to execute setApplicationVersion. Expected <String | null>, but got <number>.')
29
-
30
- apiInterface.setApplicationVersion(false)
31
- expect(console.warn).toHaveBeenCalledWith('New Relic: Failed to execute setApplicationVersion. Expected <String | null>, but got <boolean>.')
32
-
33
- apiInterface.setApplicationVersion({ version: '1.2.3' })
34
- expect(console.warn).toHaveBeenCalledWith('New Relic: Failed to execute setApplicationVersion. Expected <String | null>, but got <object>.')
35
- })
36
-
37
- test('setApplicationVersion replaces existing data if called twice', () => {
38
- apiInterface.setApplicationVersion('1.2.3')
39
- expect(getInfo('abcd').jsAttributes).toMatchObject({ 'application.version': '1.2.3' })
40
-
41
- apiInterface.setApplicationVersion('4.5.6')
42
- expect(getInfo('abcd').jsAttributes).toMatchObject({ 'application.version': '4.5.6' })
43
- })
44
- })
45
- })
@@ -1,85 +0,0 @@
1
- import { setTopLevelCallers, setAPI } from './api'
2
- import { gosCDN } from '../../common/window/nreum'
3
-
4
- jest.enableAutomock()
5
- jest.unmock('./api')
6
-
7
- describe('setTopLevelCallers', () => {
8
- beforeEach(() => {
9
- delete gosCDN().initializedAgents
10
- })
11
-
12
- test('adds all api methods', () => {
13
- setTopLevelCallers()
14
-
15
- expect(Object.keys(gosCDN()).length).toEqual(14)
16
- })
17
-
18
- test('and runs the corresponding fn under every exposed agent', () => {
19
- let newrelic = gosCDN()
20
- newrelic.initializedAgents = {
21
- abcd: { exposed: true, api: { noticeError: jest.fn() } },
22
- efgh: { exposed: false, api: { noticeError: jest.fn() } },
23
- ijkl: { exposed: true, api: { noticeError: jest.fn() } }
24
- }
25
-
26
- const someArgs = ['wtfish', { bop: 'it' }]
27
- newrelic.noticeError(...someArgs)
28
- expect(newrelic.initializedAgents.abcd.api.noticeError).toHaveBeenCalledWith(...someArgs)
29
- expect(newrelic.initializedAgents.efgh.api.noticeError).not.toHaveBeenCalled()
30
- expect(newrelic.initializedAgents.ijkl.api.noticeError).toHaveBeenCalledWith(...someArgs)
31
- })
32
-
33
- test('fn call returns right number of results based on running agent(s)', () => {
34
- let newrelic = gosCDN()
35
- newrelic.initializedAgents = {
36
- abcd: { exposed: true, api: { interaction: jest.fn(() => 'duck') } }
37
- }
38
- let ret = newrelic.interaction()
39
- expect(ret).toEqual('duck')
40
-
41
- newrelic.initializedAgents.efgh = { exposed: true, api: { interaction: jest.fn(() => 'truck') } }
42
- ret = newrelic.interaction()
43
- expect(ret).toEqual(['duck', 'truck'])
44
- })
45
- })
46
-
47
- jest.unmock('../../common/event-emitter/contextual-ee')
48
- jest.mock('../../common/constants/runtime', () => {
49
- return {
50
- __esModule: true,
51
- isBrowserScope: false
52
- }
53
- })
54
-
55
- describe('setAPI', () => {
56
- test('also adds all api methods', () => {
57
- let apiI = setAPI('abcd', true)
58
-
59
- expect(Object.keys(apiI).length).toEqual(14)
60
- for (const k of Object.keys(apiI)) { expect(apiI[k]).toBeInstanceOf(Function) }
61
- })
62
-
63
- test('sets up spa interaction api prototype/handle', () => {
64
- let apiI = setAPI('abcd', true)
65
- let interactionProto = Object.getPrototypeOf(apiI.interaction())
66
-
67
- expect(Object.keys(interactionProto).length).toEqual(10)
68
- for (const k of Object.keys(interactionProto)) { expect(interactionProto[k]).toBeInstanceOf(Function) }
69
- })
70
-
71
- test('calls asyncApi setAPI as well', async () => {
72
- jest.resetModules()
73
- let setApiCalled
74
- let asyncSetApi = new Promise(resolve => { setApiCalled = resolve })
75
- jest.doMock('./apiAsync', () => {
76
- return {
77
- __esModule: true,
78
- setAPI: jest.fn(id => setApiCalled(id))
79
- }
80
- })
81
-
82
- setAPI('abcd', true)
83
- await expect(asyncSetApi).resolves.toBe('abcd')
84
- })
85
- })
@@ -1,17 +0,0 @@
1
- import { setAPI } from './apiAsync'
2
- import * as register from '../../common/event-emitter/register-handler'
3
-
4
- jest.enableAutomock()
5
- jest.unmock('./apiAsync')
6
- jest.unmock('../../common/event-emitter/contextual-ee')
7
-
8
- test('setAPI registers all async methods', () => {
9
- let callSpy = jest.spyOn(register, 'registerHandler')
10
- setAPI('abcd')
11
-
12
- expect(callSpy).toHaveBeenCalledTimes(5)
13
- for (let i = 0; i < 5; i++) {
14
- expect(callSpy.mock.calls[i][0].startsWith('api-')).toBeTruthy()
15
- expect(callSpy.mock.calls[i][1]).toBeInstanceOf(Function)
16
- }
17
- })