@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,21 +0,0 @@
1
- let getRuntime, setRuntime
2
- beforeEach(async () => {
3
- jest.resetModules()
4
- ;({ getRuntime, setRuntime } = await import('./runtime.js'))
5
- })
6
-
7
- test('set/getRuntime should throw on an invalid agent id', () => {
8
- // currently only checks if it's a truthy value
9
- expect(() => setRuntime(undefined, {})).toThrow('require an agent id')
10
- expect(() => getRuntime(undefined)).toThrow('require an agent id')
11
- expect(() => setRuntime('', {})).toThrow('require an agent id')
12
- expect(() => getRuntime('')).toThrow('require an agent id')
13
- })
14
-
15
- test('set/getRuntime works correctly', () => {
16
- expect(() => setRuntime(123, { session: 1 })).not.toThrow() // notice setRuntime accepts numbers
17
- let cachedObj = getRuntime('123')
18
- expect(Object.keys(cachedObj).length).toBeGreaterThan(1)
19
- expect(cachedObj.session).toEqual(1)
20
- expect(cachedObj.maxBytes).toEqual(30000) // this should mirror default in runtime.js
21
- })
@@ -1,7 +0,0 @@
1
- import * as env from './env.cdn'
2
-
3
- test('should default environment variables to CDN values', async () => {
4
- expect(env.VERSION).toMatch(/\d{1,3}\.\d{1,3}\.\d{1,3}/)
5
- expect(env.BUILD_ENV).toEqual('CDN')
6
- expect(env.DIST_METHOD).toEqual('CDN')
7
- })
@@ -1,7 +0,0 @@
1
- import * as env from './env.npm'
2
-
3
- test('should default environment variables to NPM values', () => {
4
- expect(env.VERSION).toMatch(/\d{1,3}\.\d{1,3}\.\d{1,3}/)
5
- expect(env.BUILD_ENV).toEqual('NPM')
6
- expect(env.DIST_METHOD).toEqual('NPM')
7
- })
@@ -1,7 +0,0 @@
1
- import * as env from './env'
2
-
3
- test('should default environment variables to NPM values', () => {
4
- expect(env.VERSION).toMatch(/\d{1,3}\.\d{1,3}\.\d{1,3}/)
5
- expect(env.BUILD_ENV).toEqual('NPM')
6
- expect(env.DIST_METHOD).toEqual('NPM')
7
- })
@@ -1,176 +0,0 @@
1
- /**
2
- * The runtime module exports variables whose values are set at the time of import and
3
- * can depend on the environment the agent is running within. To make testing this module
4
- * easier, use async import to import the module and only use the node jest environment so
5
- * we can more easily define environment variables.
6
- * @jest-environment node
7
- */
8
-
9
- import { faker } from '@faker-js/faker'
10
-
11
- beforeEach(() => {
12
- // We assume every runtime has a global navigator variable
13
- global.navigator = {
14
- userAgent: faker.lorem.sentence()
15
- }
16
- })
17
-
18
- afterEach(() => {
19
- delete global.navigator
20
- jest.resetModules()
21
- })
22
-
23
- test('should indicate agent is running in a browser scope', async () => {
24
- const mockedWindow = global.window = {
25
- [faker.datatype.uuid()]: faker.lorem.sentence,
26
- document: {
27
- [faker.datatype.uuid()]: faker.lorem.sentence
28
- }
29
- }
30
-
31
- const runtime = await import('./runtime')
32
-
33
- delete global.window
34
-
35
- expect(runtime.isBrowserScope).toEqual(true)
36
- expect(runtime.isWorkerScope).toEqual(false)
37
- expect(runtime.globalScope).toEqual(mockedWindow)
38
- })
39
-
40
- test('should indicate agent is running in a worker scope using global self variable', async () => {
41
- global.WorkerGlobalScope = class WorkerGlobalScope {}
42
- global.WorkerNavigator = class WorkerNavigator {}
43
- const mockedGlobalSelf = global.self = new global.WorkerGlobalScope()
44
- mockedGlobalSelf.navigator = new global.WorkerNavigator()
45
-
46
- const runtime = await import('./runtime')
47
-
48
- delete global.WorkerGlobalScope
49
- delete global.WorkerNavigator
50
- delete global.self
51
-
52
- expect(runtime.isBrowserScope).toEqual(false)
53
- expect(runtime.isWorkerScope).toEqual(true)
54
- expect(runtime.globalScope).toEqual(mockedGlobalSelf)
55
- })
56
-
57
- test('should indicate agent is running in a worker scope using global self variable', async () => {
58
- global.WorkerGlobalScope = class WorkerGlobalScope {}
59
- global.WorkerNavigator = class WorkerNavigator {}
60
- const cachedGlobalThis = global.globalThis
61
- const mockedGlobalThis = global.globalThis = new WorkerGlobalScope()
62
- Object.defineProperties(global.globalThis, Object.getOwnPropertyDescriptors(cachedGlobalThis))
63
- global.globalThis.navigator = new WorkerNavigator()
64
-
65
- const runtime = await import('./runtime')
66
-
67
- delete global.WorkerGlobalScope
68
- delete global.WorkerNavigator
69
- global.globalThis = cachedGlobalThis
70
-
71
- expect(runtime.isBrowserScope).toEqual(false)
72
- expect(runtime.isWorkerScope).toEqual(true)
73
- expect(runtime.globalScope).toEqual(mockedGlobalThis)
74
- })
75
-
76
- test('should store the initial page location', async () => {
77
- const initialLocation = faker.internet.url()
78
- const mockedWindow = global.window = {
79
- [faker.datatype.uuid()]: faker.lorem.sentence,
80
- document: {
81
- [faker.datatype.uuid()]: faker.lorem.sentence
82
- },
83
- location: {
84
- href: initialLocation,
85
- toString () {
86
- return this.href
87
- }
88
- }
89
- }
90
-
91
- const runtime = await import('./runtime')
92
- mockedWindow.location.href = faker.internet.url()
93
-
94
- delete global.window
95
-
96
- expect(runtime.initialLocation).toEqual(initialLocation)
97
- expect(runtime.initialLocation).not.toEqual(mockedWindow.location.href)
98
- })
99
-
100
- test.each([
101
- { userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Mobile/15E148 Safari/604.1', expected: true },
102
- { userAgent: 'Mozilla/5.0 (iPad; CPU OS 16_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Mobile/15E148 Safari/604.1', expected: true },
103
- { userAgent: 'Mozilla/5.0 (iPod touch; CPU iPhone OS 16_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Mobile/15E148 Safari/604.1', expected: true },
104
- { userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 13_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Safari/605.1.15', expected: false },
105
- { userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/114.0', expected: false },
106
- { userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 13.4; rv:109.0) Gecko/20100101 Firefox/114.0', expected: false }
107
- ])('should set isiOS to $expected for $userAgent', async ({ userAgent, expected }) => {
108
- global.navigator.userAgent = userAgent
109
- global.window = { navigator: global.navigator, document: true }
110
-
111
- const runtime = await import('./runtime')
112
-
113
- expect(runtime.isiOS).toEqual(expected)
114
- delete global.window
115
- })
116
-
117
- test.each([
118
- { userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Mobile/15E148 Safari/604.1', expected: false },
119
- { userAgent: 'Mozilla/5.0 (iPad; CPU OS 16_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Mobile/15E148 Safari/604.1', expected: false },
120
- { userAgent: 'Mozilla/5.0 (iPod touch; CPU iPhone OS 16_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Mobile/15E148 Safari/604.1', expected: false },
121
- { userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Mobile/15E148 Safari/604.1', expected: true },
122
- { userAgent: 'Mozilla/5.0 (iPad; CPU OS 15_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Mobile/15E148 Safari/604.1', expected: true },
123
- { userAgent: 'Mozilla/5.0 (iPod touch; CPU iPhone OS 15_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Mobile/15E148 Safari/604.1', expected: true },
124
- { userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 13_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Safari/605.1.15', expected: false },
125
- { userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/114.0', expected: false },
126
- { userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 13.4; rv:109.0) Gecko/20100101 Firefox/114.0', expected: false }
127
- ])('should set iOSBelow16 to $expected for $userAgent', async ({ userAgent, expected }) => {
128
- if (!expected) {
129
- global.SharedWorker = class SharedWorker {}
130
- }
131
- global.navigator.userAgent = userAgent
132
- global.window = { navigator: global.navigator, document: true }
133
-
134
- const runtime = await import('./runtime')
135
-
136
- delete global.SharedWorker
137
-
138
- expect(runtime.iOSBelow16).toEqual(expected)
139
- delete global.window
140
- })
141
-
142
- test.each([
143
- { userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Mobile/15E148 Safari/604.1', expected: 0 },
144
- { userAgent: 'Mozilla/5.0 (iPad; CPU OS 16_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Mobile/15E148 Safari/604.1', expected: 0 },
145
- { userAgent: 'Mozilla/5.0 (iPod touch; CPU iPhone OS 16_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Mobile/15E148 Safari/604.1', expected: 0 },
146
- { userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 13_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Safari/605.1.15', expected: 0 },
147
- { userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/114.0', expected: 114 },
148
- { userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 13.4; rv:109.0) Gecko/20100101 Firefox/114.0', expected: 114 }
149
- ])('should set ffVersion to $expected for $userAgent', async ({ userAgent, expected }) => {
150
- global.navigator.userAgent = userAgent
151
- global.window = { navigator: global.navigator, document: true }
152
-
153
- const runtime = await import('./runtime')
154
-
155
- expect(runtime.ffVersion).toEqual(expected)
156
- delete global.window
157
- })
158
-
159
- test('should set supportsSendBeacon to false', async () => {
160
- // Ensure we don't have a sendBeacon function
161
- delete global.navigator.sendBeacon
162
-
163
- const runtime = await import('./runtime')
164
-
165
- expect(runtime.supportsSendBeacon).toEqual(false)
166
- })
167
-
168
- test('should set supportsSendBeacon to true', async () => {
169
- global.navigator.sendBeacon = jest.fn()
170
- global.window = { navigator: global.navigator, document: true }
171
-
172
- const runtime = await import('./runtime')
173
-
174
- expect(runtime.supportsSendBeacon).toEqual(true)
175
- delete global.window
176
- })
@@ -1,104 +0,0 @@
1
- jest.enableAutomock()
2
- jest.unmock('./deny-list')
3
-
4
- let denyListModule
5
-
6
- beforeEach(async () => {
7
- denyListModule = await import('./deny-list')
8
- })
9
-
10
- afterEach(() => {
11
- jest.resetModules()
12
- })
13
-
14
- test('domain-only blocks all subdomains and all paths', () => {
15
- denyListModule.setDenyList(['foo.com'])
16
-
17
- expect(denyListModule.shouldCollectEvent({ hostname: 'foo.com', pathname: '/' })).toBeFalsy()
18
- expect(denyListModule.shouldCollectEvent({ hostname: 'foo.com', pathname: '/a' })).toBeFalsy()
19
- expect(denyListModule.shouldCollectEvent({ hostname: 'foo.com', pathname: '/a/b' })).toBeFalsy()
20
-
21
- expect(denyListModule.shouldCollectEvent({ hostname: 'www.foo.com', pathname: '/' })).toBeFalsy()
22
- expect(denyListModule.shouldCollectEvent({ hostname: 'a.b.foo.com', pathname: '/' })).toBeFalsy()
23
- expect(denyListModule.shouldCollectEvent({ hostname: 'a.b.foo.com', pathname: '/c/d' })).toBeFalsy()
24
-
25
- expect(denyListModule.shouldCollectEvent({ hostname: 'oo.com', pathname: '/' })).toBeTruthy()
26
- expect(denyListModule.shouldCollectEvent({ hostname: 'bar.com', pathname: '/' })).toBeTruthy()
27
- })
28
-
29
- test('subdomain blocks further subdomains, but not parent domain', () => {
30
- denyListModule.setDenyList(['bar.foo.com'])
31
-
32
- expect(denyListModule.shouldCollectEvent({ hostname: 'bar.foo.com', pathname: '/' })).toBeFalsy()
33
- expect(denyListModule.shouldCollectEvent({ hostname: 'bar.foo.com', pathname: '/a' })).toBeFalsy()
34
- expect(denyListModule.shouldCollectEvent({ hostname: 'bar.foo.com', pathname: '/a/b' })).toBeFalsy()
35
-
36
- expect(denyListModule.shouldCollectEvent({ hostname: 'a.bar.foo.com', pathname: '/' })).toBeFalsy()
37
- expect(denyListModule.shouldCollectEvent({ hostname: 'a.bar.foo.com', pathname: '/a' })).toBeFalsy()
38
- expect(denyListModule.shouldCollectEvent({ hostname: 'a.bar.foo.com', pathname: '/a/b' })).toBeFalsy()
39
-
40
- expect(denyListModule.shouldCollectEvent({ hostname: 'foo.com', pathname: '/' })).toBeTruthy()
41
- expect(denyListModule.shouldCollectEvent({ hostname: 'foo.com', pathname: '/a' })).toBeTruthy()
42
- expect(denyListModule.shouldCollectEvent({ hostname: 'foo.com', pathname: '/a/b' })).toBeTruthy()
43
-
44
- expect(denyListModule.shouldCollectEvent({ hostname: 'oo.com', pathname: '/' })).toBeTruthy()
45
- expect(denyListModule.shouldCollectEvent({ hostname: 'bar.com', pathname: '/' })).toBeTruthy()
46
- })
47
-
48
- test('* blocks all domains', () => {
49
- denyListModule.setDenyList(['*'])
50
-
51
- expect(denyListModule.shouldCollectEvent({ hostname: 'foo.com', pathname: '/' })).toBeFalsy()
52
- expect(denyListModule.shouldCollectEvent({ hostname: 'www.foo.com', pathname: '/' })).toBeFalsy()
53
- expect(denyListModule.shouldCollectEvent({ hostname: 'bar.com', pathname: '/' })).toBeFalsy()
54
- expect(denyListModule.shouldCollectEvent({ hostname: 'www.bar.com', pathname: '/' })).toBeFalsy()
55
- })
56
-
57
- test('respects path', () => {
58
- denyListModule.setDenyList(['bam.nr-data.net/somepath'])
59
-
60
- expect(denyListModule.shouldCollectEvent({ hostname: 'bam.nr-data.net', pathname: '/somepath' })).toBeFalsy()
61
- expect(denyListModule.shouldCollectEvent({ hostname: 'bam.nr-data.net', port: '7890', protocol: 'https', host: 'bam.nr-data.net:7890', pathname: '/somepath' })).toBeFalsy()
62
-
63
- expect(denyListModule.shouldCollectEvent({ hostname: 'bam.nr-data.com', pathname: '' })).toBeTruthy()
64
- expect(denyListModule.shouldCollectEvent({ hostname: 'bam.nr-data.com', pathname: '/someotherpath' })).toBeTruthy()
65
- expect(denyListModule.shouldCollectEvent({ hostname: 'bam.nr-data.com', pathname: '/some/otherpath' })).toBeTruthy()
66
- })
67
-
68
- test('ignores port', () => {
69
- denyListModule.setDenyList(['bam.nr-data.net:1234'])
70
-
71
- expect(denyListModule.shouldCollectEvent({ hostname: 'bam.nr-data.net', pathname: '', port: '4321' })).toBeFalsy()
72
- expect(denyListModule.shouldCollectEvent({ hostname: 'bam.nr-data.net', port: '7890', protocol: 'http', host: 'bam.nr-data.net:7890', pathname: '/somepath' })).toBeFalsy()
73
-
74
- expect(denyListModule.shouldCollectEvent({ hostname: 'bam.nr-data.com', pathname: '' })).toBeTruthy()
75
- })
76
-
77
- test('ignores protocol', () => {
78
- denyListModule.setDenyList(['http://bam.nr-data.net'])
79
-
80
- expect(denyListModule.shouldCollectEvent({ hostname: 'bam.nr-data.net', pathname: '', protocol: 'https' })).toBeFalsy()
81
- expect(denyListModule.shouldCollectEvent({ hostname: 'bam.nr-data.net', port: '7890', protocol: 'https', host: 'bam.nr-data.net:7890', pathname: '/somepath' })).toBeFalsy()
82
-
83
- expect(denyListModule.shouldCollectEvent({ hostname: 'bam.nr-data.com', pathname: '', protocol: 'http' })).toBeTruthy()
84
- })
85
-
86
- test.each([
87
- null,
88
- undefined,
89
- '!@$%^*',
90
- 'https://example.com/http://foo.bar/'
91
- ])('ignores invalid deny list value %s', (denyListValue) => {
92
- denyListModule.setDenyList([denyListValue])
93
-
94
- expect(denyListModule.shouldCollectEvent({ hostname: 'foo.com', pathname: '/' })).toBeTruthy()
95
- expect(denyListModule.shouldCollectEvent({ hostname: 'foo.com', pathname: '/a' })).toBeTruthy()
96
- expect(denyListModule.shouldCollectEvent({ hostname: 'foo.com', pathname: '/a/b' })).toBeTruthy()
97
-
98
- expect(denyListModule.shouldCollectEvent({ hostname: 'www.foo.com', pathname: '/' })).toBeTruthy()
99
- expect(denyListModule.shouldCollectEvent({ hostname: 'a.b.foo.com', pathname: '/' })).toBeTruthy()
100
- expect(denyListModule.shouldCollectEvent({ hostname: 'a.b.foo.com', pathname: '/c/d' })).toBeTruthy()
101
-
102
- expect(denyListModule.shouldCollectEvent({ hostname: 'oo.com', pathname: '/' })).toBeTruthy()
103
- expect(denyListModule.shouldCollectEvent({ hostname: 'bar.com', pathname: '/' })).toBeTruthy()
104
- })
@@ -1,74 +0,0 @@
1
- let registerDrain, drain, ee
2
- beforeEach(async () => {
3
- jest.resetModules()
4
- ;({ registerDrain, drain } = await import('./drain'))
5
- ;({ ee } = await import('../event-emitter/contextual-ee'))
6
- })
7
-
8
- test('can register a feat and drain it', () => {
9
- registerDrain('abcd', 'page_view_event')
10
-
11
- let emitSpy = jest.spyOn(ee.get('abcd'), 'emit')
12
- drain('abcd', 'page_view_event')
13
- expect(emitSpy).toHaveBeenCalledWith('drain-page_view_event', expect.anything())
14
- })
15
-
16
- test('other unregistered drains do not affect feat reg & drain', () => {
17
- registerDrain('abcd', 'page_view_event')
18
-
19
- let emitSpy = jest.spyOn(ee.get('abcd'), 'emit')
20
- drain('abcd', 'timon')
21
- expect(emitSpy).toHaveBeenCalledWith('drain-timon', expect.anything())
22
- expect(emitSpy).not.toHaveBeenCalledWith('drain-page_view_event', expect.anything())
23
-
24
- drain('abcd', 'page_view_event')
25
- expect(emitSpy).toHaveBeenCalledWith('drain-page_view_event', expect.anything())
26
- })
27
-
28
- describe('drain', () => {
29
- test('does not execute until all registered groups calls it and in order', () => {
30
- registerDrain('abcd', 'page_view_timing')
31
- registerDrain('abcd', 'page_view_event')
32
-
33
- let emitSpy = jest.spyOn(ee.get('abcd'), 'emit')
34
- drain('abcd', 'page_view_event')
35
- expect(emitSpy).not.toHaveBeenCalled()
36
-
37
- drain('abcd', 'page_view_timing')
38
- // The priority order of features is also checked here, even though the latter was registered first.
39
- expect(emitSpy).toHaveBeenNthCalledWith(1, 'drain-page_view_event', expect.anything())
40
- expect(emitSpy).toHaveBeenNthCalledWith(2, 'drain-page_view_timing', expect.anything())
41
- })
42
-
43
- test('does not require registration for non-feat groups', () => {
44
- let emitSpy = jest.spyOn(ee.get('abcd'), 'emit')
45
- drain('abcd', 'pumbaa')
46
- expect(emitSpy).toHaveBeenCalledWith('drain-pumbaa', expect.anything())
47
- })
48
-
49
- test('defaults to "feature" group when not provided one', () => {
50
- let emitSpy = jest.spyOn(ee.get('abcd'), 'emit')
51
- drain('abcd')
52
- expect(emitSpy).toHaveBeenCalledWith('drain-feature', expect.anything())
53
- })
54
-
55
- test('works on the global ee when agent id not provided', () => {
56
- let emitSpy = jest.spyOn(ee, 'emit')
57
- drain()
58
- expect(emitSpy).toHaveBeenCalledWith('drain-feature', expect.anything())
59
- })
60
- })
61
-
62
- test('non-feat groups can register and drain too alongside features', () => {
63
- registerDrain('abcd', 'page_view_event')
64
- registerDrain('abcd', 'simba')
65
-
66
- console.log(JSON.stringify(ee.get('abcd')))
67
- let emitSpy = jest.spyOn(ee.get('abcd'), 'emit')
68
- drain('abcd', 'simba')
69
- expect(emitSpy).not.toHaveBeenCalled()
70
-
71
- drain('abcd', 'page_view_event')
72
- expect(emitSpy).toHaveBeenNthCalledWith(1, 'drain-simba', expect.anything()) // non-feat have prio of 0
73
- expect(emitSpy).toHaveBeenNthCalledWith(2, 'drain-page_view_event', expect.anything())
74
- })