@newrelic/browser-agent 0.1.230 → 0.1.231
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.
- package/README.md +25 -1
- package/dist/cjs/common/browser-version/ios-version.js +4 -3
- package/dist/cjs/common/config/state/configurable.js +1 -1
- package/dist/cjs/common/config/state/info.js +1 -1
- package/dist/cjs/common/config/state/init.js +1 -1
- package/dist/cjs/common/config/state/loader-config.js +1 -1
- package/dist/cjs/common/config/state/runtime.js +5 -5
- package/dist/cjs/common/constants/env.cdn.js +29 -0
- package/dist/cjs/common/constants/env.js +32 -0
- package/dist/cjs/common/constants/env.npm.js +30 -0
- package/dist/cjs/common/event-emitter/contextual-ee.test.js +282 -0
- package/dist/cjs/common/event-emitter/handle.test.js +58 -0
- package/dist/cjs/common/event-emitter/register-handler.test.js +55 -0
- package/dist/cjs/common/harvest/harvest.js +2 -2
- package/dist/cjs/common/ids/id.js +14 -6
- package/dist/cjs/common/ids/id.test.js +85 -0
- package/dist/cjs/common/ids/unique-id.js +75 -51
- package/dist/cjs/common/ids/unique-id.test.js +49 -0
- package/dist/cjs/common/timing/nav-timing.js +51 -30
- package/dist/cjs/common/timing/nav-timing.test.js +192 -0
- package/dist/cjs/common/url/clean-url.test.js +9 -0
- package/dist/cjs/common/url/encode.test.js +74 -0
- package/dist/cjs/common/url/location.js +4 -0
- package/dist/cjs/common/url/location.test.js +13 -0
- package/dist/cjs/common/url/parse-url.test.js +111 -0
- package/dist/cjs/common/url/protocol.js +2 -12
- package/dist/cjs/common/url/protocol.test.js +16 -0
- package/dist/cjs/common/util/console.js +1 -1
- package/dist/cjs/common/util/map-own.test.js +3 -3
- package/dist/cjs/common/util/obfuscate.js +1 -1
- package/dist/cjs/common/window/page-visibility.js +2 -1
- package/dist/cjs/common/wrap/index.js +0 -7
- package/dist/cjs/common/wrap/wrap-events.js +6 -9
- package/dist/cjs/common/wrap/wrap-fetch.js +6 -6
- package/dist/cjs/common/wrap/wrap-history.js +7 -6
- package/dist/cjs/common/wrap/wrap-jsonp.js +7 -6
- package/dist/cjs/common/wrap/wrap-mutation.js +7 -6
- package/dist/cjs/common/wrap/wrap-promise.js +7 -6
- package/dist/cjs/common/wrap/wrap-promise.test.js +119 -0
- package/dist/cjs/common/wrap/wrap-raf.js +6 -6
- package/dist/cjs/common/wrap/wrap-timer.js +6 -6
- package/dist/cjs/common/wrap/wrap-xhr.js +5 -6
- package/dist/cjs/features/ajax/aggregate/index.js +1 -1
- package/dist/cjs/features/jserrors/aggregate/compute-stack-trace.test.js +5 -5
- package/dist/cjs/features/jserrors/aggregate/format-stack-trace.test.js +1 -1
- package/dist/cjs/features/jserrors/aggregate/index.js +3 -3
- package/dist/cjs/features/jserrors/instrument/index.js +2 -2
- package/dist/cjs/features/metrics/aggregate/index.js +6 -7
- package/dist/cjs/features/metrics/instrument/index.js +0 -25
- package/dist/cjs/features/metrics/instrument/workers-helper.js +5 -5
- package/dist/cjs/features/page_action/aggregate/index.js +1 -1
- package/dist/cjs/features/page_view_event/aggregate/index.js +17 -6
- package/dist/cjs/features/page_view_timing/aggregate/index.js +36 -26
- package/dist/cjs/features/session_trace/aggregate/index.js +16 -13
- package/dist/cjs/features/utils/instrument-base.js +6 -2
- package/dist/cjs/features/utils/lazy-loader.js +1 -1
- package/dist/cjs/loaders/agent.js +1 -1
- package/dist/cjs/loaders/api/api.js +8 -5
- package/dist/cjs/loaders/features/enabled-features.js +1 -1
- package/dist/cjs/loaders/micro-agent.js +2 -1
- package/dist/esm/common/browser-version/ios-version.js +4 -3
- package/dist/esm/common/config/state/configurable.js +1 -1
- package/dist/esm/common/config/state/info.js +1 -1
- package/dist/esm/common/config/state/init.js +1 -1
- package/dist/esm/common/config/state/loader-config.js +1 -1
- package/dist/esm/common/config/state/runtime.js +2 -2
- package/dist/esm/common/constants/env.cdn.js +20 -0
- package/dist/esm/common/constants/env.js +23 -0
- package/dist/esm/common/constants/env.npm.js +21 -0
- package/dist/esm/common/event-emitter/contextual-ee.test.js +278 -0
- package/dist/esm/common/event-emitter/handle.test.js +54 -0
- package/dist/esm/common/event-emitter/register-handler.test.js +51 -0
- package/dist/esm/common/harvest/harvest.js +1 -1
- package/dist/esm/common/ids/id.js +16 -6
- package/dist/esm/common/ids/id.test.js +81 -0
- package/dist/esm/common/ids/unique-id.js +75 -51
- package/dist/esm/common/ids/unique-id.test.js +44 -0
- package/dist/esm/common/timing/nav-timing.js +51 -29
- package/dist/esm/common/timing/nav-timing.test.js +190 -0
- package/dist/esm/common/url/clean-url.test.js +7 -0
- package/dist/esm/common/url/encode.test.js +70 -0
- package/dist/esm/common/url/location.js +4 -0
- package/dist/esm/common/url/location.test.js +11 -0
- package/dist/esm/common/url/parse-url.test.js +107 -0
- package/dist/esm/common/url/protocol.js +3 -12
- package/dist/esm/common/url/protocol.test.js +14 -0
- package/dist/esm/common/util/console.js +1 -1
- package/dist/esm/common/util/map-own.test.js +3 -3
- package/dist/esm/common/util/obfuscate.js +2 -2
- package/dist/esm/common/window/page-visibility.js +2 -1
- package/dist/esm/common/wrap/index.js +1 -2
- package/dist/esm/common/wrap/wrap-events.js +6 -9
- package/dist/esm/common/wrap/wrap-fetch.js +6 -6
- package/dist/esm/common/wrap/wrap-history.js +7 -6
- package/dist/esm/common/wrap/wrap-jsonp.js +7 -6
- package/dist/esm/common/wrap/wrap-mutation.js +7 -6
- package/dist/esm/common/wrap/wrap-promise.js +7 -6
- package/dist/esm/common/wrap/wrap-promise.test.js +115 -0
- package/dist/esm/common/wrap/wrap-raf.js +6 -6
- package/dist/esm/common/wrap/wrap-timer.js +6 -6
- package/dist/esm/common/wrap/wrap-xhr.js +5 -6
- package/dist/esm/features/ajax/aggregate/index.js +1 -1
- package/dist/esm/features/jserrors/aggregate/compute-stack-trace.test.js +5 -5
- package/dist/esm/features/jserrors/aggregate/format-stack-trace.test.js +1 -1
- package/dist/esm/features/jserrors/aggregate/index.js +3 -3
- package/dist/esm/features/jserrors/instrument/index.js +2 -2
- package/dist/esm/features/metrics/aggregate/index.js +7 -8
- package/dist/esm/features/metrics/instrument/index.js +0 -25
- package/dist/esm/features/metrics/instrument/workers-helper.js +5 -5
- package/dist/esm/features/page_action/aggregate/index.js +1 -1
- package/dist/esm/features/page_view_event/aggregate/index.js +17 -6
- package/dist/esm/features/page_view_timing/aggregate/index.js +36 -26
- package/dist/esm/features/session_trace/aggregate/index.js +16 -13
- package/dist/esm/features/utils/instrument-base.js +1 -1
- package/dist/esm/features/utils/lazy-loader.js +1 -1
- package/dist/esm/loaders/agent.js +1 -1
- package/dist/esm/loaders/api/api.js +4 -4
- package/dist/esm/loaders/features/enabled-features.js +1 -1
- package/dist/types/common/config/state/runtime.d.ts.map +1 -1
- package/dist/types/common/constants/env.cdn.d.ts +18 -0
- package/dist/types/common/constants/env.cdn.d.ts.map +1 -0
- package/dist/types/common/constants/env.d.ts +13 -0
- package/dist/types/common/constants/env.d.ts.map +1 -0
- package/dist/types/common/constants/env.npm.d.ts +19 -0
- package/dist/types/common/constants/env.npm.d.ts.map +1 -0
- package/dist/types/common/ids/id.d.ts +11 -1
- package/dist/types/common/ids/id.d.ts.map +1 -1
- package/dist/types/common/ids/unique-id.d.ts +24 -1
- package/dist/types/common/ids/unique-id.d.ts.map +1 -1
- package/dist/types/common/timing/nav-timing.d.ts +1 -2
- package/dist/types/common/timing/nav-timing.d.ts.map +1 -1
- package/dist/types/common/unload/eol.d.ts.map +1 -1
- package/dist/types/common/url/location.d.ts +4 -0
- package/dist/types/common/url/location.d.ts.map +1 -1
- package/dist/types/common/url/parse-url.d.ts.map +1 -1
- package/dist/types/common/url/protocol.d.ts +1 -6
- package/dist/types/common/url/protocol.d.ts.map +1 -1
- package/dist/types/common/util/global-scope.d.ts.map +1 -1
- package/dist/types/common/wrap/index.d.ts +1 -2
- package/dist/types/common/wrap/index.d.ts.map +1 -1
- package/dist/types/common/wrap/wrap-fetch.d.ts.map +1 -1
- package/dist/types/common/wrap/wrap-history.d.ts.map +1 -1
- package/dist/types/common/wrap/wrap-jsonp.d.ts.map +1 -1
- package/dist/types/common/wrap/wrap-mutation.d.ts.map +1 -1
- package/dist/types/common/wrap/wrap-promise.d.ts.map +1 -1
- package/dist/types/common/wrap/wrap-raf.d.ts.map +1 -1
- package/dist/types/common/wrap/wrap-timer.d.ts.map +1 -1
- package/dist/types/common/wrap/wrap-xhr.d.ts.map +1 -1
- package/dist/types/features/jserrors/instrument/index.d.ts.map +1 -1
- package/dist/types/features/metrics/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/metrics/instrument/index.d.ts +0 -1
- package/dist/types/features/metrics/instrument/index.d.ts.map +1 -1
- package/dist/types/features/metrics/instrument/workers-helper.d.ts.map +1 -1
- package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/page_view_timing/aggregate/index.d.ts +1 -2
- package/dist/types/features/page_view_timing/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_trace/aggregate/index.d.ts +1 -1
- package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_trace/instrument/index.d.ts.map +1 -1
- package/dist/types/features/spa/instrument/index.d.ts.map +1 -1
- package/package.json +9 -30
- package/src/common/browser-version/ios-version.js +4 -3
- package/src/common/config/state/runtime.js +26 -24
- package/src/common/constants/env.cdn.js +20 -0
- package/src/common/constants/env.js +23 -0
- package/src/common/constants/env.npm.js +21 -0
- package/src/common/event-emitter/contextual-ee.test.js +310 -0
- package/src/common/event-emitter/handle.test.js +56 -0
- package/src/common/event-emitter/register-handler.test.js +61 -0
- package/src/common/harvest/harvest.js +2 -2
- package/src/common/ids/id.js +15 -6
- package/src/common/ids/id.test.js +92 -0
- package/src/common/ids/unique-id.js +77 -54
- package/src/common/ids/unique-id.test.js +58 -0
- package/src/common/timing/nav-timing.js +50 -30
- package/src/common/timing/nav-timing.test.js +161 -0
- package/src/common/unload/eol.js +1 -2
- package/src/common/url/clean-url.test.js +25 -0
- package/src/common/url/encode.test.js +80 -0
- package/src/common/url/location.js +4 -0
- package/src/common/url/location.test.js +15 -0
- package/src/common/url/parse-url.js +1 -2
- package/src/common/url/parse-url.test.js +110 -0
- package/src/common/url/protocol.js +3 -13
- package/src/common/url/protocol.test.js +18 -0
- package/src/common/util/global-scope.js +1 -2
- package/src/common/util/obfuscate.js +2 -2
- package/src/common/window/page-visibility.js +1 -1
- package/src/common/wrap/index.js +1 -2
- package/src/common/wrap/wrap-events.js +5 -5
- package/src/common/wrap/wrap-fetch.js +4 -3
- package/src/common/wrap/wrap-history.js +6 -3
- package/src/common/wrap/wrap-jsonp.js +5 -3
- package/src/common/wrap/wrap-mutation.js +6 -3
- package/src/common/wrap/wrap-promise.js +7 -6
- package/src/common/wrap/wrap-promise.test.js +140 -0
- package/src/common/wrap/wrap-raf.js +5 -3
- package/src/common/wrap/wrap-timer.js +5 -3
- package/src/common/wrap/wrap-xhr.js +4 -3
- package/src/features/ajax/instrument/index.js +1 -1
- package/src/features/jserrors/instrument/index.js +4 -2
- package/src/features/metrics/aggregate/index.js +3 -4
- package/src/features/metrics/instrument/index.js +0 -30
- package/src/features/metrics/instrument/workers-helper.js +9 -6
- package/src/features/page_view_event/aggregate/index.js +15 -6
- package/src/features/page_view_timing/aggregate/index.js +36 -25
- package/src/features/page_view_timing/long-tasks.js +10 -10
- package/src/features/session_trace/aggregate/index.js +15 -12
- package/src/features/session_trace/instrument/index.js +3 -2
- package/src/features/spa/instrument/index.js +4 -2
- package/src/loaders/api/api.js +1 -1
- package/dist/cjs/common/constants/environment-variables.js +0 -20
- package/dist/cjs/common/wrap/wrap-console.js +0 -54
- package/dist/esm/common/constants/environment-variables.js +0 -11
- package/dist/esm/common/wrap/wrap-console.js +0 -46
- package/dist/types/common/constants/environment-variables.d.ts +0 -4
- package/dist/types/common/constants/environment-variables.d.ts.map +0 -1
- package/dist/types/common/wrap/wrap-console.d.ts +0 -16
- package/dist/types/common/wrap/wrap-console.d.ts.map +0 -1
- package/src/common/constants/environment-variables.js +0 -11
- package/src/common/wrap/wrap-console.js +0 -47
|
@@ -4,72 +4,96 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { globalScope } from '../util/global-scope';
|
|
7
|
+
const uuidv4Template = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Creates a random single hexadecimal value from a provided random value
|
|
11
|
+
* table and corresponding index. If a random value table is not provided,
|
|
12
|
+
* Math.random will be used to generate the value.
|
|
13
|
+
*
|
|
14
|
+
* @param {Uint8Array} valueTable Random value table typically generated using
|
|
15
|
+
* the built-in crypto engine.
|
|
16
|
+
* @param {int} tableIndex The index of the value table to use for generating
|
|
17
|
+
* the hexadecimal value.
|
|
18
|
+
* @returns {int} single hexadecimal value in decimal format
|
|
19
|
+
*/
|
|
20
|
+
function getRandomValue(valueTable, tableIndex) {
|
|
21
|
+
if (valueTable) {
|
|
22
|
+
/**
|
|
23
|
+
* The value table could have any number value in the given index. Use
|
|
24
|
+
* bitwise AND to ensure the value we generate is a valid hex value.
|
|
25
|
+
* x & 15 will ensure the value converted to hex using `toString(16)`
|
|
26
|
+
* falls within the range of 0 and 15 inclusively.
|
|
27
|
+
*/
|
|
28
|
+
return valueTable[tableIndex] & 15;
|
|
29
|
+
} else {
|
|
30
|
+
return Math.random() * 16 | 0;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Generates a RFC compliant UUIDv4 using native browser crypto engine. If the browser
|
|
36
|
+
* does not support the crypto engine, the function will fallback to insecure Math.random()
|
|
37
|
+
* @returns {string} uuid version 4 string
|
|
38
|
+
*/
|
|
7
39
|
export function generateUuid() {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
40
|
+
const crypto = globalScope?.crypto || globalScope?.msCrypto;
|
|
41
|
+
let randomValueTable;
|
|
42
|
+
let randomValueIndex = 0;
|
|
11
43
|
if (crypto && crypto.getRandomValues) {
|
|
12
44
|
// eslint-disable-next-line
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
function getRandomValue() {
|
|
16
|
-
if (randomVals) {
|
|
17
|
-
// same as % 16
|
|
18
|
-
return randomVals[rvIndex++] & 15;
|
|
19
|
-
} else {
|
|
20
|
-
return Math.random() * 16 | 0;
|
|
21
|
-
}
|
|
45
|
+
randomValueTable = crypto.getRandomValues(new Uint8Array(31));
|
|
22
46
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
var c;
|
|
28
|
-
for (var i = 0; i < template.length; i++) {
|
|
29
|
-
c = template[i];
|
|
30
|
-
if (c === 'x') {
|
|
31
|
-
id += getRandomValue().toString(16);
|
|
32
|
-
} else if (c === 'y') {
|
|
47
|
+
return uuidv4Template.split('').map(templateInput => {
|
|
48
|
+
if (templateInput === 'x') {
|
|
49
|
+
return getRandomValue(randomValueTable, ++randomValueIndex).toString(16);
|
|
50
|
+
} else if (templateInput === 'y') {
|
|
33
51
|
// this is the uuid variant per spec (8, 9, a, b)
|
|
34
52
|
// % 4, then shift to get values 8-11
|
|
35
|
-
|
|
36
|
-
id += c.toString(16);
|
|
53
|
+
return (getRandomValue() & 0x3 | 0x8).toString(16);
|
|
37
54
|
} else {
|
|
38
|
-
|
|
55
|
+
return templateInput;
|
|
39
56
|
}
|
|
57
|
+
}).join('');
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Generates a string of the given length containing only hexadecimal
|
|
62
|
+
* value 0-9 and a-f.
|
|
63
|
+
* @param {int} length length of the string to generate
|
|
64
|
+
* @returns {string} generated hex string
|
|
65
|
+
*/
|
|
66
|
+
export function generateRandomHexString(length) {
|
|
67
|
+
const crypto = globalScope?.crypto || globalScope?.msCrypto;
|
|
68
|
+
let randomValueTable;
|
|
69
|
+
let randomValueIndex = 0;
|
|
70
|
+
if (crypto && crypto.getRandomValues) {
|
|
71
|
+
// eslint-disable-next-line
|
|
72
|
+
randomValueTable = crypto.getRandomValues(new Uint8Array(31));
|
|
40
73
|
}
|
|
41
|
-
|
|
74
|
+
const chars = [];
|
|
75
|
+
for (var i = 0; i < length; i++) {
|
|
76
|
+
chars.push(getRandomValue(randomValueTable, ++randomValueIndex).toString(16));
|
|
77
|
+
}
|
|
78
|
+
return chars.join('');
|
|
42
79
|
}
|
|
43
80
|
|
|
44
|
-
|
|
81
|
+
/**
|
|
82
|
+
* Generates a 16 character length hexadecimal string.
|
|
83
|
+
* per DT-spec.
|
|
84
|
+
* @see generateRandomHexString
|
|
85
|
+
* @returns {string} generated hex string
|
|
86
|
+
*/
|
|
45
87
|
export function generateSpanId() {
|
|
46
88
|
return generateRandomHexString(16);
|
|
47
89
|
}
|
|
48
90
|
|
|
49
|
-
|
|
91
|
+
/**
|
|
92
|
+
* Generates a 32 character length hexadecimal string.
|
|
93
|
+
* per DT-spec.
|
|
94
|
+
* @see generateRandomHexString
|
|
95
|
+
* @returns {string} generated hex string
|
|
96
|
+
*/
|
|
50
97
|
export function generateTraceId() {
|
|
51
98
|
return generateRandomHexString(32);
|
|
52
|
-
}
|
|
53
|
-
export function generateRandomHexString(length) {
|
|
54
|
-
var randomVals = null;
|
|
55
|
-
var rvIndex = 0;
|
|
56
|
-
var crypto = self.crypto || self.msCrypto;
|
|
57
|
-
// eslint-disable-next-line
|
|
58
|
-
if (crypto && crypto.getRandomValues && Uint8Array) {
|
|
59
|
-
// eslint-disable-next-line
|
|
60
|
-
randomVals = crypto.getRandomValues(new Uint8Array(31));
|
|
61
|
-
}
|
|
62
|
-
var chars = [];
|
|
63
|
-
for (var i = 0; i < length; i++) {
|
|
64
|
-
chars.push(getRandomValue().toString(16));
|
|
65
|
-
}
|
|
66
|
-
return chars.join('');
|
|
67
|
-
function getRandomValue() {
|
|
68
|
-
if (randomVals) {
|
|
69
|
-
// same as % 16
|
|
70
|
-
return randomVals[rvIndex++] & 15;
|
|
71
|
-
} else {
|
|
72
|
-
return Math.random() * 16 | 0;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
99
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import crypto from 'crypto';
|
|
2
|
+
import * as uniqueId from './unique-id';
|
|
3
|
+
const getRandomValues = jest.fn(arr => crypto.randomBytes(arr.length));
|
|
4
|
+
afterEach(() => {
|
|
5
|
+
delete global.crypto;
|
|
6
|
+
});
|
|
7
|
+
describe('generateUuid', () => {
|
|
8
|
+
const uuidv4Regex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
|
|
9
|
+
test('should generate a uuidv4 that matches the expected format', () => {
|
|
10
|
+
const id = uniqueId.generateUuid();
|
|
11
|
+
expect(uuidv4Regex.test(id)).toEqual(true);
|
|
12
|
+
});
|
|
13
|
+
test('should support using native crypto library', () => {
|
|
14
|
+
global.crypto = {
|
|
15
|
+
getRandomValues
|
|
16
|
+
};
|
|
17
|
+
const id = uniqueId.generateUuid();
|
|
18
|
+
expect(uuidv4Regex.test(id)).toEqual(true);
|
|
19
|
+
expect(getRandomValues).toHaveBeenCalledTimes(1);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
describe('generateRandomHexString', () => {
|
|
23
|
+
const hexRegex = /^[0-9a-f]{8}$/;
|
|
24
|
+
test('should generate a valid hex string', () => {
|
|
25
|
+
const id = uniqueId.generateRandomHexString(8);
|
|
26
|
+
expect(hexRegex.test(id)).toEqual(true);
|
|
27
|
+
});
|
|
28
|
+
test('should support using native crypto library', () => {
|
|
29
|
+
global.crypto = {
|
|
30
|
+
getRandomValues
|
|
31
|
+
};
|
|
32
|
+
const id = uniqueId.generateRandomHexString(8);
|
|
33
|
+
expect(hexRegex.test(id)).toEqual(true);
|
|
34
|
+
expect(getRandomValues).toHaveBeenCalledTimes(1);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
test('generateSpanId should generate a 16 character hex string', () => {
|
|
38
|
+
const id = uniqueId.generateSpanId();
|
|
39
|
+
expect(/^[0-9a-f]{16}$/.test(id)).toEqual(true);
|
|
40
|
+
});
|
|
41
|
+
test('generateTraceId should generate a 32 character hex string', () => {
|
|
42
|
+
const id = uniqueId.generateTraceId();
|
|
43
|
+
expect(/^[0-9a-f]{32}$/.test(id)).toEqual(true);
|
|
44
|
+
});
|
|
@@ -25,43 +25,65 @@ var RESPONSE = 'response';
|
|
|
25
25
|
var LOAD_EVENT = 'loadEvent';
|
|
26
26
|
var DOM_CONTENT_LOAD_EVENT = 'domContentLoadedEvent';
|
|
27
27
|
export var navTimingValues = [];
|
|
28
|
-
|
|
28
|
+
function getPntType(type) {
|
|
29
|
+
if (typeof type == 'number') return type;
|
|
30
|
+
const types = {
|
|
31
|
+
navigate: undefined,
|
|
32
|
+
reload: 1,
|
|
33
|
+
back_forward: 2,
|
|
34
|
+
prerender: 3
|
|
35
|
+
};
|
|
36
|
+
return types[type];
|
|
37
|
+
}
|
|
38
|
+
export function addPT(offset, pt) {
|
|
39
|
+
let v = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
40
|
+
let isL1Api = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
41
|
+
if (!pt) return;
|
|
29
42
|
v.of = offset;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
43
|
+
handleValue(v.of, v, 'n', true);
|
|
44
|
+
handleValue(pt[UNLOAD_EVENT + START], v, 'u', isL1Api);
|
|
45
|
+
handleValue(pt[REDIRECT + START], v, 'r', isL1Api);
|
|
46
|
+
handleValue(pt[UNLOAD_EVENT + END], v, 'ue', isL1Api);
|
|
47
|
+
handleValue(pt[REDIRECT + END], v, 're', isL1Api);
|
|
48
|
+
handleValue(pt['fetch' + START], v, 'f', isL1Api);
|
|
49
|
+
handleValue(pt[DOMAIN_LOOKUP + START], v, 'dn', isL1Api);
|
|
50
|
+
handleValue(pt[DOMAIN_LOOKUP + END], v, 'dne', isL1Api);
|
|
51
|
+
handleValue(pt['c' + ONNECT + START], v, 'c', isL1Api);
|
|
52
|
+
handleValue(pt['secureC' + ONNECT + 'ion' + START], v, 's', isL1Api);
|
|
53
|
+
handleValue(pt['c' + ONNECT + END], v, 'ce', isL1Api);
|
|
54
|
+
handleValue(pt[REQUEST + START], v, 'rq', isL1Api);
|
|
55
|
+
handleValue(pt[RESPONSE + START], v, 'rp', isL1Api);
|
|
56
|
+
handleValue(pt[RESPONSE + END], v, 'rpe', isL1Api);
|
|
57
|
+
handleValue(pt.domLoading, v, 'dl', isL1Api);
|
|
58
|
+
handleValue(pt.domInteractive, v, 'di', isL1Api);
|
|
59
|
+
handleValue(pt[DOM_CONTENT_LOAD_EVENT + START], v, 'ds', isL1Api);
|
|
60
|
+
handleValue(pt[DOM_CONTENT_LOAD_EVENT + END], v, 'de', isL1Api);
|
|
61
|
+
handleValue(pt.domComplete, v, 'dc', isL1Api);
|
|
62
|
+
handleValue(pt[LOAD_EVENT + START], v, 'l', isL1Api);
|
|
63
|
+
handleValue(pt[LOAD_EVENT + END], v, 'le', isL1Api);
|
|
51
64
|
return v;
|
|
52
65
|
}
|
|
53
66
|
|
|
54
67
|
// Add Performance Navigation values to the given object
|
|
55
68
|
export function addPN(pn, v) {
|
|
56
|
-
|
|
57
|
-
|
|
69
|
+
handleValue(getPntType(pn.type), v, 'ty');
|
|
70
|
+
handleValue(pn.redirectCount, v, 'rc');
|
|
58
71
|
return v;
|
|
59
72
|
}
|
|
60
|
-
|
|
61
|
-
|
|
73
|
+
function handleValue(value, obj, prop, isOldApi) {
|
|
74
|
+
/*
|
|
75
|
+
For L2 Timing API, the value will already be a relative-to-previous-document DOMHighResTimeStamp.
|
|
76
|
+
For L1 (deprecated) Timing, the value is an UNIX epoch timestamp, which we will convert to a relative time using our offset.
|
|
77
|
+
PNT.type is reported as undefined, 1, 2, etc -- note that zero-value properties will be recorded as 'undefined', however DEM interprets undefined "types" as "navigate"
|
|
78
|
+
*/
|
|
62
79
|
if (typeof value === 'number' && value > 0) {
|
|
63
|
-
|
|
64
|
-
|
|
80
|
+
// note that zero-value properties will be recorded as 'undefined'
|
|
81
|
+
if (isOldApi) {
|
|
82
|
+
const offset = obj?.of > 0 ? obj.of : 0; // expect an epoch timestamp, if called by addPT
|
|
83
|
+
value = Math.max(value - offset, 0);
|
|
84
|
+
}
|
|
85
|
+
value = Math.round(value);
|
|
86
|
+
obj[prop] = value;
|
|
65
87
|
}
|
|
66
|
-
navTimingValues.push(
|
|
88
|
+
navTimingValues.push(value);
|
|
67
89
|
}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { addPT, addPN, navTimingValues } from './nav-timing';
|
|
2
|
+
const offset = 123;
|
|
3
|
+
const testValues = {
|
|
4
|
+
unloadEventStart: 1,
|
|
5
|
+
redirectStart: 2,
|
|
6
|
+
unloadEventEnd: 3,
|
|
7
|
+
redirectEnd: 4,
|
|
8
|
+
fetchStart: 5,
|
|
9
|
+
domainLookupStart: 6,
|
|
10
|
+
domainLookupEnd: 7,
|
|
11
|
+
connectStart: 8,
|
|
12
|
+
secureConnectionStart: 9,
|
|
13
|
+
connectEnd: 10,
|
|
14
|
+
requestStart: 11,
|
|
15
|
+
responseStart: 12,
|
|
16
|
+
responseEnd: 13,
|
|
17
|
+
domLoading: 14,
|
|
18
|
+
domInteractive: 15,
|
|
19
|
+
domContentLoadedEventStart: 16,
|
|
20
|
+
domContentLoadedEventEnd: 17,
|
|
21
|
+
domComplete: 18,
|
|
22
|
+
loadEventStart: 19,
|
|
23
|
+
loadEventEnd: 20,
|
|
24
|
+
type: 'reload',
|
|
25
|
+
redirectCount: 22
|
|
26
|
+
};
|
|
27
|
+
const legacyTestValues = {
|
|
28
|
+
unloadEventStart: offset + 1,
|
|
29
|
+
redirectStart: offset + 2,
|
|
30
|
+
unloadEventEnd: offset + 3,
|
|
31
|
+
redirectEnd: offset + 4,
|
|
32
|
+
fetchStart: offset + 5,
|
|
33
|
+
domainLookupStart: offset + 6,
|
|
34
|
+
domainLookupEnd: offset + 7,
|
|
35
|
+
connectStart: offset + 8,
|
|
36
|
+
secureConnectionStart: offset + 9,
|
|
37
|
+
connectEnd: offset + 10,
|
|
38
|
+
requestStart: offset + 11,
|
|
39
|
+
responseStart: offset + 12,
|
|
40
|
+
responseEnd: offset + 13,
|
|
41
|
+
domLoading: offset + 14,
|
|
42
|
+
domInteractive: offset + 15,
|
|
43
|
+
domContentLoadedEventStart: offset + 16,
|
|
44
|
+
domContentLoadedEventEnd: offset + 17,
|
|
45
|
+
domComplete: offset + 18,
|
|
46
|
+
loadEventStart: offset + 19,
|
|
47
|
+
loadEventEnd: offset + 20,
|
|
48
|
+
type: 'reload',
|
|
49
|
+
redirectCount: offset + 22
|
|
50
|
+
};
|
|
51
|
+
const expectedPT = {
|
|
52
|
+
of: offset,
|
|
53
|
+
n: 0,
|
|
54
|
+
u: 1,
|
|
55
|
+
r: 2,
|
|
56
|
+
ue: 3,
|
|
57
|
+
re: 4,
|
|
58
|
+
f: 5,
|
|
59
|
+
dn: 6,
|
|
60
|
+
dne: 7,
|
|
61
|
+
c: 8,
|
|
62
|
+
s: 9,
|
|
63
|
+
ce: 10,
|
|
64
|
+
rq: 11,
|
|
65
|
+
rp: 12,
|
|
66
|
+
rpe: 13,
|
|
67
|
+
dl: 14,
|
|
68
|
+
di: 15,
|
|
69
|
+
ds: 16,
|
|
70
|
+
de: 17,
|
|
71
|
+
dc: 18,
|
|
72
|
+
l: 19,
|
|
73
|
+
le: 20
|
|
74
|
+
};
|
|
75
|
+
const expectedPN = {
|
|
76
|
+
ty: 1,
|
|
77
|
+
rc: 22
|
|
78
|
+
};
|
|
79
|
+
describe('addPT()', () => {
|
|
80
|
+
test('an output object is populated with valid values', () => {
|
|
81
|
+
const output = addPT(offset, testValues, {});
|
|
82
|
+
expect(output).toEqual(expectedPT);
|
|
83
|
+
});
|
|
84
|
+
test('an object with invalid values is handled', () => {
|
|
85
|
+
const output = addPT(offset, {
|
|
86
|
+
...testValues,
|
|
87
|
+
invalidValue: 'test'
|
|
88
|
+
}, {});
|
|
89
|
+
expect(output).toEqual(expectedPT);
|
|
90
|
+
const output2 = addPT(offset, {
|
|
91
|
+
...testValues,
|
|
92
|
+
loadEventEnd: -1
|
|
93
|
+
}, {});
|
|
94
|
+
let expected = {
|
|
95
|
+
...expectedPT
|
|
96
|
+
};
|
|
97
|
+
delete expected.le;
|
|
98
|
+
expect(output2).toEqual(expected);
|
|
99
|
+
const output3 = addPT(offset, {
|
|
100
|
+
...testValues,
|
|
101
|
+
loadEventEnd: 'test'
|
|
102
|
+
}, {});
|
|
103
|
+
expected = {
|
|
104
|
+
...expectedPT
|
|
105
|
+
};
|
|
106
|
+
delete expected.le;
|
|
107
|
+
expect(output3).toEqual(expected);
|
|
108
|
+
const output4 = addPT(offset, {
|
|
109
|
+
...testValues,
|
|
110
|
+
loadEventEnd: null
|
|
111
|
+
}, {});
|
|
112
|
+
expected = {
|
|
113
|
+
...expectedPT
|
|
114
|
+
};
|
|
115
|
+
delete expected.le;
|
|
116
|
+
expect(output4).toEqual(expected);
|
|
117
|
+
const legacyoutput = addPT(offset, {
|
|
118
|
+
...legacyTestValues,
|
|
119
|
+
invalidValue: 'test'
|
|
120
|
+
}, {}, true);
|
|
121
|
+
expect(legacyoutput).toEqual(expectedPT);
|
|
122
|
+
const legacyoutput2 = addPT(offset, {
|
|
123
|
+
...legacyTestValues,
|
|
124
|
+
loadEventEnd: -1
|
|
125
|
+
}, {}, true);
|
|
126
|
+
let legacyexpected = {
|
|
127
|
+
...expectedPT
|
|
128
|
+
};
|
|
129
|
+
delete legacyexpected.le;
|
|
130
|
+
expect(legacyoutput2).toEqual(expected);
|
|
131
|
+
const legacyoutput3 = addPT(offset, {
|
|
132
|
+
...legacyTestValues,
|
|
133
|
+
loadEventEnd: 'test'
|
|
134
|
+
}, {}, true);
|
|
135
|
+
legacyexpected = {
|
|
136
|
+
...expectedPT
|
|
137
|
+
};
|
|
138
|
+
delete legacyexpected.le;
|
|
139
|
+
expect(legacyoutput3).toEqual(legacyexpected);
|
|
140
|
+
const legacyoutput4 = addPT(offset, {
|
|
141
|
+
...legacyTestValues,
|
|
142
|
+
loadEventEnd: null
|
|
143
|
+
}, {}, true);
|
|
144
|
+
legacyexpected = {
|
|
145
|
+
...expectedPT
|
|
146
|
+
};
|
|
147
|
+
delete legacyexpected.le;
|
|
148
|
+
expect(legacyoutput4).toEqual(legacyexpected);
|
|
149
|
+
});
|
|
150
|
+
test('rounds values to integers', () => {
|
|
151
|
+
const output = addPT(offset, {
|
|
152
|
+
unloadEventStart: 3.14159
|
|
153
|
+
}, {});
|
|
154
|
+
expect(output.u).toEqual(3);
|
|
155
|
+
const legacyoutput = addPT(0, {
|
|
156
|
+
unloadEventStart: 3.14159
|
|
157
|
+
}, {}, true);
|
|
158
|
+
expect(legacyoutput.u).toEqual(3);
|
|
159
|
+
});
|
|
160
|
+
test('adds entries to navTimingValues', () => {
|
|
161
|
+
const beforeLength = navTimingValues.length;
|
|
162
|
+
addPT(offset, {
|
|
163
|
+
testValues
|
|
164
|
+
}, {});
|
|
165
|
+
const afterLength = navTimingValues.length;
|
|
166
|
+
expect(afterLength - beforeLength).toEqual(21); // 20 + value of n
|
|
167
|
+
|
|
168
|
+
const legacybeforeLength = navTimingValues.length;
|
|
169
|
+
addPT(offset, {
|
|
170
|
+
legacyTestValues
|
|
171
|
+
}, {}, true);
|
|
172
|
+
const legacyafterLength = navTimingValues.length;
|
|
173
|
+
expect(legacyafterLength - legacybeforeLength).toEqual(21); // 20 + value of n
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
describe('addPN()', () => {
|
|
178
|
+
test('an output object is populated with valid values', () => {
|
|
179
|
+
const output = addPN(testValues, {});
|
|
180
|
+
expect(output).toEqual(expectedPN);
|
|
181
|
+
});
|
|
182
|
+
test('adds entries to navTimingValues', () => {
|
|
183
|
+
const beforeLength = navTimingValues.length;
|
|
184
|
+
addPN(offset, {
|
|
185
|
+
testValues
|
|
186
|
+
}, {});
|
|
187
|
+
const afterLength = navTimingValues.length;
|
|
188
|
+
expect(afterLength - beforeLength).toEqual(2);
|
|
189
|
+
});
|
|
190
|
+
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { cleanURL } from './clean-url';
|
|
2
|
+
test.each([['http://domain.com/path?query=5', 'http://domain.com/path'], ['http://domain.com/path#fragment', 'http://domain.com/path'], ['http://domain.com/path?query=5#fragment', 'http://domain.com/path'], ['http://domain.com/path?query=5?dumb#fragment', 'http://domain.com/path'], ['http://domain.com/path?query=5#fragment#dumb', 'http://domain.com/path'], ['http://domain.com/path?query=5#fragment#dumb?additional_query', 'http://domain.com/path'], ['http://domain.com/path?query=5#fragment/silly/dumber#dumbest?additional_query=silly#what_is_this_even', 'http://domain.com/path']])('cleanURL should remove hash', (input, expected) => {
|
|
3
|
+
expect(cleanURL(input)).toEqual(expected);
|
|
4
|
+
});
|
|
5
|
+
test.each([['http://domain.com/path?query=5', 'http://domain.com/path'], ['http://domain.com/path#fragment', 'http://domain.com/path#fragment'], ['http://domain.com/path?query=5#fragment', 'http://domain.com/path#fragment'], ['http://domain.com/path?query=5?dumb#fragment', 'http://domain.com/path#fragment'], ['http://domain.com/path?query=5#fragment#dumb', 'http://domain.com/path#fragment#dumb'], ['http://domain.com/path?query=5#fragment#dumb?additional_query', 'http://domain.com/path#fragment#dumb'], ['http://domain.com/path?query=5#fragment/silly/dumber#dumbest?additional_query=silly#what_is_this_even', 'http://domain.com/path#fragment/silly/dumber#dumbest']])('cleanURL should retain hash if second argument is true', (input, expected) => {
|
|
6
|
+
expect(cleanURL(input, true)).toEqual(expected);
|
|
7
|
+
});
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import * as encode from './encode';
|
|
2
|
+
describe('query string encoding', () => {
|
|
3
|
+
test('escapes string components except safe characters', () => {
|
|
4
|
+
const input = 'Asdf:, :, /@$;';
|
|
5
|
+
const expected = 'Asdf:,%20:,%20/@$;';
|
|
6
|
+
expect(encode.qs(input)).toEqual(expected);
|
|
7
|
+
});
|
|
8
|
+
test('null and undefined value returns \'null\'', () => {
|
|
9
|
+
expect(encode.qs(null)).toEqual('null');
|
|
10
|
+
expect(encode.qs(undefined)).toEqual('null');
|
|
11
|
+
});
|
|
12
|
+
});
|
|
13
|
+
describe('fromArray encoding', () => {
|
|
14
|
+
test('cuts cleanly at end of byte', () => {
|
|
15
|
+
const input = ['a', 'b', 'c'];
|
|
16
|
+
const expected = 'ab';
|
|
17
|
+
expect(encode.fromArray(input, 2)).toEqual(expected);
|
|
18
|
+
});
|
|
19
|
+
test('fall back to largest whole chunk', () => {
|
|
20
|
+
const input = ['aa', 'bb', 'cc'];
|
|
21
|
+
const expected = 'aabb';
|
|
22
|
+
expect(encode.fromArray(input, 5)).toEqual(expected);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
describe('object encoding', () => {
|
|
26
|
+
test('cuts cleanly at end of byte', () => {
|
|
27
|
+
const input = {
|
|
28
|
+
foo: [1, 2, 3]
|
|
29
|
+
};
|
|
30
|
+
const expected = '&foo=%5B1,2%5D';
|
|
31
|
+
expect(encode.obj(input, 12)).toEqual(expected);
|
|
32
|
+
});
|
|
33
|
+
test('fall back to largest whole chunk', () => {
|
|
34
|
+
const input = {
|
|
35
|
+
bar: ['a', 'b', 'c']
|
|
36
|
+
};
|
|
37
|
+
const expected = '&bar=%5B%22a%22,%22b%22%5D';
|
|
38
|
+
expect(encode.obj(input, 30)).toEqual(expected);
|
|
39
|
+
});
|
|
40
|
+
test('handles circular objects', () => {
|
|
41
|
+
const circular = {};
|
|
42
|
+
circular.circular = circular;
|
|
43
|
+
const input = {
|
|
44
|
+
bar: ['a', circular, 'c']
|
|
45
|
+
};
|
|
46
|
+
const expected = '&bar=%5B%22a%22,%7B%7D,%22c%22%5D';
|
|
47
|
+
expect(encode.obj(input, 1000)).toEqual(expected);
|
|
48
|
+
});
|
|
49
|
+
test('handles circular arrays', () => {
|
|
50
|
+
const circular = [];
|
|
51
|
+
circular.push(circular);
|
|
52
|
+
const input = {
|
|
53
|
+
bar: ['a', circular, 'c']
|
|
54
|
+
};
|
|
55
|
+
const expected = '&bar=%5B%22a%22,%5Bnull%5D,%22c%22%5D';
|
|
56
|
+
expect(encode.obj(input, 1000)).toEqual(expected);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
describe('encode key value pairs as query params', () => {
|
|
60
|
+
test('ignores input when value is null or undefined', () => {
|
|
61
|
+
expect(encode.param('foo', null)).toEqual('');
|
|
62
|
+
expect(encode.param('foo', undefined)).toEqual('');
|
|
63
|
+
});
|
|
64
|
+
test('encodes key value pair correctly', () => {
|
|
65
|
+
expect(encode.param('foo', 'bar')).toEqual('&foo=bar');
|
|
66
|
+
});
|
|
67
|
+
test('ignores input when value is not a string', () => {
|
|
68
|
+
expect(encode.param('foo', {})).toEqual('');
|
|
69
|
+
});
|
|
70
|
+
});
|
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* This method only exists to support testing in JIL and can be removed once tests are migrated to WDIO.
|
|
8
|
+
* @returns global scope location
|
|
9
|
+
*/
|
|
6
10
|
export function getLocation() {
|
|
7
11
|
return '' + location;
|
|
8
12
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { faker } from '@faker-js/faker';
|
|
2
|
+
import { getLocation } from './location';
|
|
3
|
+
test('should always return a string', () => {
|
|
4
|
+
jest.spyOn(window, 'location', 'get').mockReturnValue({});
|
|
5
|
+
expect(typeof getLocation()).toEqual('string');
|
|
6
|
+
});
|
|
7
|
+
test('should return window location', () => {
|
|
8
|
+
const expected = faker.internet.url();
|
|
9
|
+
jest.spyOn(window, 'location', 'get').mockReturnValue(expected);
|
|
10
|
+
expect(getLocation()).toEqual(expected);
|
|
11
|
+
});
|