@newrelic/browser-agent 1.241.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 (132) hide show
  1. package/CHANGELOG.md +1465 -0
  2. package/dist/cjs/cdn/polyfills/lite.js +13 -1
  3. package/dist/cjs/cdn/polyfills/pro.js +17 -1
  4. package/dist/cjs/cdn/polyfills/spa.js +18 -1
  5. package/dist/cjs/common/config/state/init.js +32 -5
  6. package/dist/cjs/common/constants/env.cdn.js +1 -1
  7. package/dist/cjs/common/constants/env.npm.js +1 -1
  8. package/dist/cjs/common/dom/query-selector.js +16 -0
  9. package/dist/cjs/common/session/session-entity.js +20 -2
  10. package/dist/cjs/common/wrap/wrap-function.js +1 -1
  11. package/dist/cjs/features/ajax/aggregate/index.js +1 -1
  12. package/dist/cjs/features/session_replay/aggregate/index.js +84 -50
  13. package/dist/cjs/features/utils/feature-base.js +1 -2
  14. package/dist/cjs/features/utils/instrument-base.js +1 -0
  15. package/dist/cjs/loaders/api/api.js +2 -2
  16. package/dist/cjs/loaders/api/apiAsync.js +0 -37
  17. package/dist/cjs/loaders/configure/configure.js +1 -1
  18. package/dist/cjs/loaders/configure/public-path.js +6 -3
  19. package/dist/esm/cdn/polyfills/lite.js +8 -1
  20. package/dist/esm/cdn/polyfills/pro.js +13 -2
  21. package/dist/esm/cdn/polyfills/spa.js +13 -1
  22. package/dist/esm/common/config/state/init.js +32 -5
  23. package/dist/esm/common/constants/env.cdn.js +1 -1
  24. package/dist/esm/common/constants/env.npm.js +1 -1
  25. package/dist/esm/common/dom/query-selector.js +9 -0
  26. package/dist/esm/common/session/session-entity.js +18 -1
  27. package/dist/esm/common/wrap/wrap-function.js +1 -1
  28. package/dist/esm/features/ajax/aggregate/index.js +1 -1
  29. package/dist/esm/features/session_replay/aggregate/index.js +83 -50
  30. package/dist/esm/features/utils/feature-base.js +1 -2
  31. package/dist/esm/features/utils/instrument-base.js +1 -0
  32. package/dist/esm/loaders/api/api.js +2 -2
  33. package/dist/esm/loaders/api/apiAsync.js +1 -36
  34. package/dist/esm/loaders/configure/configure.js +1 -1
  35. package/dist/esm/loaders/configure/public-path.js +6 -3
  36. package/dist/types/common/config/state/init.d.ts.map +1 -1
  37. package/dist/types/common/dom/query-selector.d.ts +2 -0
  38. package/dist/types/common/dom/query-selector.d.ts.map +1 -0
  39. package/dist/types/common/session/session-entity.d.ts +5 -0
  40. package/dist/types/common/session/session-entity.d.ts.map +1 -1
  41. package/dist/types/features/session_replay/aggregate/index.d.ts +11 -14
  42. package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
  43. package/dist/types/features/utils/feature-base.d.ts.map +1 -1
  44. package/dist/types/features/utils/instrument-base.d.ts.map +1 -1
  45. package/dist/types/loaders/api/api.d.ts.map +1 -1
  46. package/dist/types/loaders/api/apiAsync.d.ts.map +1 -1
  47. package/dist/types/loaders/configure/public-path.d.ts +1 -1
  48. package/dist/types/loaders/configure/public-path.d.ts.map +1 -1
  49. package/package.json +2 -2
  50. package/src/cdn/polyfills/lite.js +14 -1
  51. package/src/cdn/polyfills/pro.js +23 -2
  52. package/src/cdn/polyfills/spa.js +24 -1
  53. package/src/common/config/state/init.js +33 -4
  54. package/src/common/dom/query-selector.js +9 -0
  55. package/src/common/session/session-entity.js +20 -1
  56. package/src/common/wrap/wrap-function.js +1 -1
  57. package/src/features/ajax/aggregate/index.js +2 -2
  58. package/src/features/session_replay/aggregate/index.js +82 -34
  59. package/src/features/utils/feature-base.js +1 -2
  60. package/src/features/utils/instrument-base.js +1 -0
  61. package/src/loaders/api/api.js +1 -2
  62. package/src/loaders/api/apiAsync.js +1 -39
  63. package/src/loaders/configure/configure.js +1 -1
  64. package/src/loaders/configure/public-path.js +6 -3
  65. package/src/common/aggregate/aggregator.test.js +0 -107
  66. package/src/common/config/state/configurable.test.js +0 -73
  67. package/src/common/config/state/info.test.js +0 -31
  68. package/src/common/config/state/init.test.js +0 -28
  69. package/src/common/config/state/loader-config.test.js +0 -21
  70. package/src/common/config/state/runtime.test.js +0 -21
  71. package/src/common/constants/env.cdn.test.js +0 -7
  72. package/src/common/constants/env.npm.test.js +0 -7
  73. package/src/common/constants/env.test.js +0 -7
  74. package/src/common/constants/runtime.test.js +0 -176
  75. package/src/common/deny-list/deny-list.test.js +0 -104
  76. package/src/common/drain/drain.test.js +0 -74
  77. package/src/common/event-emitter/contextual-ee.component-test.js +0 -293
  78. package/src/common/event-emitter/handle.test.js +0 -56
  79. package/src/common/event-emitter/register-handler.test.js +0 -61
  80. package/src/common/harvest/harvest-scheduler.test.js +0 -492
  81. package/src/common/harvest/harvest.test.js +0 -813
  82. package/src/common/ids/id.test.js +0 -92
  83. package/src/common/ids/unique-id.test.js +0 -58
  84. package/src/common/session/session-entity.component-test.js +0 -346
  85. package/src/common/storage/local-storage.test.js +0 -17
  86. package/src/common/timer/interaction-timer.component-test.js +0 -212
  87. package/src/common/timer/timer.test.js +0 -99
  88. package/src/common/timing/nav-timing.test.js +0 -161
  89. package/src/common/url/canonicalize-url.test.js +0 -45
  90. package/src/common/url/clean-url.test.js +0 -25
  91. package/src/common/url/encode.test.js +0 -81
  92. package/src/common/url/location.test.js +0 -15
  93. package/src/common/url/parse-url.test.js +0 -110
  94. package/src/common/url/protocol.test.js +0 -17
  95. package/src/common/util/console.test.js +0 -34
  96. package/src/common/util/data-size.test.js +0 -56
  97. package/src/common/util/feature-flags.test.js +0 -94
  98. package/src/common/util/get-or-set.test.js +0 -58
  99. package/src/common/util/invoke.test.js +0 -65
  100. package/src/common/util/map-own.test.js +0 -52
  101. package/src/common/util/obfuscate.component-test.js +0 -173
  102. package/src/common/util/stringify.test.js +0 -49
  103. package/src/common/util/submit-data.test.js +0 -183
  104. package/src/common/util/traverse.test.js +0 -50
  105. package/src/common/vitals/cumulative-layout-shift.test.js +0 -71
  106. package/src/common/vitals/first-contentful-paint.test.js +0 -124
  107. package/src/common/vitals/first-input-delay.test.js +0 -88
  108. package/src/common/vitals/first-paint.test.js +0 -127
  109. package/src/common/vitals/interaction-to-next-paint.test.js +0 -74
  110. package/src/common/vitals/largest-contentful-paint.test.js +0 -94
  111. package/src/common/vitals/long-task.test.js +0 -122
  112. package/src/common/vitals/time-to-first-byte.test.js +0 -147
  113. package/src/common/vitals/vital-metric.test.js +0 -171
  114. package/src/common/wrap/wrap-promise.component-test.js +0 -110
  115. package/src/features/ajax/instrument/distributed-tracing.test.js +0 -375
  116. package/src/features/jserrors/aggregate/canonical-function-name.test.js +0 -13
  117. package/src/features/jserrors/aggregate/compute-stack-trace.test.js +0 -414
  118. package/src/features/jserrors/aggregate/format-stack-trace.test.js +0 -39
  119. package/src/features/jserrors/aggregate/string-hash-code.test.js +0 -12
  120. package/src/features/metrics/aggregate/framework-detection.test.js +0 -332
  121. package/src/features/page_view_timing/aggregate/index.component-test.js +0 -86
  122. package/src/features/session_replay/aggregate/index.component-test.js +0 -317
  123. package/src/features/spa/aggregate/interaction-node.test.js +0 -17
  124. package/src/features/utils/agent-session.test.js +0 -194
  125. package/src/features/utils/aggregate-base.test.js +0 -123
  126. package/src/features/utils/feature-base.test.js +0 -45
  127. package/src/features/utils/handler-cache.test.js +0 -72
  128. package/src/features/utils/instrument-base.test.js +0 -216
  129. package/src/features/utils/lazy-feature-loader.test.js +0 -37
  130. package/src/loaders/api/api.component-test.js +0 -45
  131. package/src/loaders/api/api.test.js +0 -85
  132. 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
- })