swetrix 4.0.0 → 4.2.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.
- package/README.md +204 -14
- package/dist/esnext/Lib.d.ts +6 -0
- package/dist/esnext/Lib.js +3 -1
- package/dist/esnext/Lib.js.map +1 -1
- package/dist/esnext/utils.d.ts +9 -0
- package/dist/esnext/utils.js +27 -3
- package/dist/esnext/utils.js.map +1 -1
- package/dist/swetrix.cjs.js +29 -3
- package/dist/swetrix.cjs.js.map +1 -1
- package/dist/swetrix.es5.js +29 -3
- package/dist/swetrix.es5.js.map +1 -1
- package/dist/swetrix.js +1 -1
- package/dist/swetrix.js.map +1 -1
- package/jest.config.js +1 -1
- package/package.json +41 -41
- package/src/Lib.ts +10 -0
- package/src/utils.ts +31 -3
- package/tests/errors.test.ts +2 -9
- package/tests/events.test.ts +2 -9
- package/tests/experiments.test.ts +2 -9
- package/tests/initialisation.test.ts +5 -18
- package/tests/jsdomEnvironment.ts +20 -0
- package/tests/pageview.test.ts +3 -9
- package/tests/testUtils.ts +27 -0
- package/tests/utils.test.ts +37 -114
- package/.github/funding.yml +0 -2
- package/.github/workflows/test.yml +0 -32
package/tests/utils.test.ts
CHANGED
|
@@ -1,35 +1,32 @@
|
|
|
1
1
|
import * as utils from '../src/utils'
|
|
2
|
+
import { setLocation } from './testUtils'
|
|
2
3
|
|
|
3
4
|
describe('Utility Functions', () => {
|
|
4
5
|
beforeEach(() => {
|
|
5
|
-
|
|
6
|
-
value: {
|
|
7
|
-
hostname: 'example.com',
|
|
8
|
-
pathname: '/test-page',
|
|
9
|
-
hash: '',
|
|
10
|
-
search: '',
|
|
11
|
-
},
|
|
12
|
-
writable: true,
|
|
13
|
-
})
|
|
6
|
+
setLocation({ hostname: 'example.com', pathname: '/test-page' })
|
|
14
7
|
|
|
15
8
|
Object.defineProperty(document, 'referrer', {
|
|
16
9
|
value: 'https://google.com',
|
|
17
10
|
writable: true,
|
|
11
|
+
configurable: true,
|
|
18
12
|
})
|
|
19
13
|
|
|
20
14
|
Object.defineProperty(navigator, 'language', {
|
|
21
15
|
value: 'en-US',
|
|
22
16
|
writable: true,
|
|
17
|
+
configurable: true,
|
|
23
18
|
})
|
|
24
19
|
|
|
25
20
|
Object.defineProperty(navigator, 'languages', {
|
|
26
21
|
value: ['en-US', 'en'],
|
|
27
22
|
writable: true,
|
|
23
|
+
configurable: true,
|
|
28
24
|
})
|
|
29
25
|
|
|
30
26
|
Object.defineProperty(navigator, 'webdriver', {
|
|
31
27
|
value: false,
|
|
32
28
|
writable: true,
|
|
29
|
+
configurable: true,
|
|
33
30
|
})
|
|
34
31
|
})
|
|
35
32
|
|
|
@@ -38,50 +35,28 @@ describe('Utility Functions', () => {
|
|
|
38
35
|
})
|
|
39
36
|
|
|
40
37
|
test('isLocalhost should detect localhost', () => {
|
|
41
|
-
|
|
42
|
-
Object.defineProperty(window, 'location', {
|
|
43
|
-
value: {
|
|
44
|
-
hostname: 'localhost',
|
|
45
|
-
},
|
|
46
|
-
writable: true,
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
// Act & Assert
|
|
38
|
+
setLocation({ hostname: 'localhost' })
|
|
50
39
|
expect(utils.isLocalhost()).toBe(true)
|
|
51
40
|
|
|
52
|
-
|
|
53
|
-
Object.defineProperty(window, 'location', {
|
|
54
|
-
value: {
|
|
55
|
-
hostname: '127.0.0.1',
|
|
56
|
-
},
|
|
57
|
-
writable: true,
|
|
58
|
-
})
|
|
41
|
+
setLocation({ hostname: '127.0.0.1' })
|
|
59
42
|
expect(utils.isLocalhost()).toBe(true)
|
|
60
43
|
|
|
61
|
-
|
|
62
|
-
Object.defineProperty(window, 'location', {
|
|
63
|
-
value: {
|
|
64
|
-
hostname: 'example.com',
|
|
65
|
-
},
|
|
66
|
-
writable: true,
|
|
67
|
-
})
|
|
44
|
+
setLocation({ hostname: 'example.com' })
|
|
68
45
|
expect(utils.isLocalhost()).toBe(false)
|
|
69
46
|
})
|
|
70
47
|
|
|
71
48
|
test('isAutomated should detect webdriver', () => {
|
|
72
|
-
// Arrange
|
|
73
49
|
Object.defineProperty(navigator, 'webdriver', {
|
|
74
50
|
value: true,
|
|
75
51
|
writable: true,
|
|
52
|
+
configurable: true,
|
|
76
53
|
})
|
|
77
|
-
|
|
78
|
-
// Act & Assert
|
|
79
54
|
expect(utils.isAutomated()).toBe(true)
|
|
80
55
|
|
|
81
|
-
// Test non-automated
|
|
82
56
|
Object.defineProperty(navigator, 'webdriver', {
|
|
83
57
|
value: false,
|
|
84
58
|
writable: true,
|
|
59
|
+
configurable: true,
|
|
85
60
|
})
|
|
86
61
|
expect(utils.isAutomated()).toBe(false)
|
|
87
62
|
})
|
|
@@ -89,129 +64,77 @@ describe('Utility Functions', () => {
|
|
|
89
64
|
test('getLocale should return the browser language', () => {
|
|
90
65
|
expect(utils.getLocale()).toBe('en-US')
|
|
91
66
|
|
|
92
|
-
// Test with navigator.languages undefined
|
|
93
67
|
const originalLanguages = navigator.languages
|
|
94
|
-
// Instead of deleting, set to undefined
|
|
95
68
|
Object.defineProperty(navigator, 'languages', {
|
|
96
69
|
value: undefined,
|
|
97
70
|
writable: true,
|
|
71
|
+
configurable: true,
|
|
98
72
|
})
|
|
99
|
-
expect(utils.getLocale()).toBe('en-US')
|
|
73
|
+
expect(utils.getLocale()).toBe('en-US')
|
|
100
74
|
|
|
101
|
-
// Restore the original value
|
|
102
75
|
Object.defineProperty(navigator, 'languages', {
|
|
103
76
|
value: originalLanguages,
|
|
104
77
|
writable: true,
|
|
78
|
+
configurable: true,
|
|
105
79
|
})
|
|
106
80
|
})
|
|
107
81
|
|
|
108
82
|
test('getReferrer should return the document referrer', () => {
|
|
109
83
|
expect(utils.getReferrer()).toBe('https://google.com')
|
|
110
84
|
|
|
111
|
-
// Test with empty referrer
|
|
112
85
|
Object.defineProperty(document, 'referrer', {
|
|
113
86
|
value: '',
|
|
114
87
|
writable: true,
|
|
88
|
+
configurable: true,
|
|
115
89
|
})
|
|
116
90
|
expect(utils.getReferrer()).toBeUndefined()
|
|
117
91
|
})
|
|
118
92
|
|
|
119
|
-
test('
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
value: {
|
|
123
|
-
pathname: '/test-page',
|
|
124
|
-
hash: '',
|
|
125
|
-
search: '',
|
|
126
|
-
},
|
|
127
|
-
writable: true,
|
|
128
|
-
})
|
|
93
|
+
test('getQueryString should return the URL query string without the leading ?', () => {
|
|
94
|
+
setLocation({ pathname: '/landing', search: '?fbclid=AbCdEf123&utm_source=newsletter' })
|
|
95
|
+
expect(utils.getQueryString()).toBe('fbclid=AbCdEf123&utm_source=newsletter')
|
|
129
96
|
|
|
130
|
-
|
|
97
|
+
setLocation({ pathname: '/landing' })
|
|
98
|
+
expect(utils.getQueryString()).toBeUndefined()
|
|
99
|
+
|
|
100
|
+
// Hash-routed SPAs sometimes carry the query string after the `#`.
|
|
101
|
+
setLocation({ pathname: '/', hash: '#/landing?gclid=xyz' })
|
|
102
|
+
expect(utils.getQueryString()).toBe('gclid=xyz')
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
test('getPath should handle different URL formats', () => {
|
|
106
|
+
setLocation({ pathname: '/test-page' })
|
|
131
107
|
expect(utils.getPath({})).toBe('/test-page')
|
|
132
108
|
|
|
133
|
-
|
|
134
|
-
Object.defineProperty(window, 'location', {
|
|
135
|
-
value: {
|
|
136
|
-
pathname: '/test-page',
|
|
137
|
-
hash: '#section1',
|
|
138
|
-
search: '',
|
|
139
|
-
},
|
|
140
|
-
writable: true,
|
|
141
|
-
})
|
|
109
|
+
setLocation({ pathname: '/test-page', hash: '#section1' })
|
|
142
110
|
expect(utils.getPath({ hash: true })).toBe('/test-page#section1')
|
|
143
111
|
|
|
144
|
-
|
|
145
|
-
Object.defineProperty(window, 'location', {
|
|
146
|
-
value: {
|
|
147
|
-
pathname: '/test-page',
|
|
148
|
-
hash: '',
|
|
149
|
-
search: '?param=value',
|
|
150
|
-
},
|
|
151
|
-
writable: true,
|
|
152
|
-
})
|
|
112
|
+
setLocation({ pathname: '/test-page', search: '?param=value' })
|
|
153
113
|
expect(utils.getPath({ search: true })).toBe('/test-page?param=value')
|
|
154
114
|
|
|
155
|
-
|
|
156
|
-
Object.defineProperty(window, 'location', {
|
|
157
|
-
value: {
|
|
158
|
-
pathname: '/test-page',
|
|
159
|
-
hash: '#section1',
|
|
160
|
-
search: '?param=value',
|
|
161
|
-
},
|
|
162
|
-
writable: true,
|
|
163
|
-
})
|
|
115
|
+
setLocation({ pathname: '/test-page', hash: '#section1', search: '?param=value' })
|
|
164
116
|
expect(utils.getPath({ hash: true, search: true })).toBe('/test-page#section1?param=value')
|
|
165
117
|
|
|
166
|
-
|
|
167
|
-
Object.defineProperty(window, 'location', {
|
|
168
|
-
value: {
|
|
169
|
-
pathname: '/test-page',
|
|
170
|
-
hash: '#section1?param=value',
|
|
171
|
-
search: '',
|
|
172
|
-
},
|
|
173
|
-
writable: true,
|
|
174
|
-
})
|
|
118
|
+
setLocation({ pathname: '/test-page', hash: '#section1?param=value' })
|
|
175
119
|
expect(utils.getPath({ hash: true, search: true })).toBe('/test-page#section1?param=value')
|
|
176
120
|
})
|
|
177
121
|
|
|
178
122
|
test('getUTM* functions should extract UTM parameters', () => {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
pathname: '/landing',
|
|
183
|
-
hash: '',
|
|
184
|
-
search: '?utm_source=google&utm_medium=cpc&utm_campaign=summer&utm_term=analytics&utm_content=ad1',
|
|
185
|
-
},
|
|
186
|
-
writable: true,
|
|
123
|
+
setLocation({
|
|
124
|
+
pathname: '/landing',
|
|
125
|
+
search: '?utm_source=google&utm_medium=cpc&utm_campaign=summer&utm_term=analytics&utm_content=ad1',
|
|
187
126
|
})
|
|
188
127
|
|
|
189
|
-
// Act & Assert
|
|
190
128
|
expect(utils.getUTMSource()).toBe('google')
|
|
191
129
|
expect(utils.getUTMMedium()).toBe('cpc')
|
|
192
130
|
expect(utils.getUTMCampaign()).toBe('summer')
|
|
193
131
|
expect(utils.getUTMTerm()).toBe('analytics')
|
|
194
132
|
expect(utils.getUTMContent()).toBe('ad1')
|
|
195
133
|
|
|
196
|
-
|
|
197
|
-
Object.defineProperty(window, 'location', {
|
|
198
|
-
value: {
|
|
199
|
-
pathname: '/landing',
|
|
200
|
-
hash: '',
|
|
201
|
-
search: '?ref=twitter',
|
|
202
|
-
},
|
|
203
|
-
writable: true,
|
|
204
|
-
})
|
|
134
|
+
setLocation({ pathname: '/landing', search: '?ref=twitter' })
|
|
205
135
|
expect(utils.getUTMSource()).toBe('twitter')
|
|
206
136
|
|
|
207
|
-
|
|
208
|
-
value: {
|
|
209
|
-
pathname: '/landing',
|
|
210
|
-
hash: '',
|
|
211
|
-
search: '?source=newsletter',
|
|
212
|
-
},
|
|
213
|
-
writable: true,
|
|
214
|
-
})
|
|
137
|
+
setLocation({ pathname: '/landing', search: '?source=newsletter' })
|
|
215
138
|
expect(utils.getUTMSource()).toBe('newsletter')
|
|
216
139
|
})
|
|
217
140
|
})
|
package/.github/funding.yml
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
name: Tests
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches: [main]
|
|
6
|
-
pull_request:
|
|
7
|
-
branches: [main]
|
|
8
|
-
types: [opened, labeled, synchronize, ready_for_review]
|
|
9
|
-
|
|
10
|
-
jobs:
|
|
11
|
-
test:
|
|
12
|
-
name: 🧪 Unit Tests
|
|
13
|
-
runs-on: ubuntu-latest
|
|
14
|
-
|
|
15
|
-
strategy:
|
|
16
|
-
matrix:
|
|
17
|
-
node-version: [22.x]
|
|
18
|
-
|
|
19
|
-
steps:
|
|
20
|
-
- uses: actions/checkout@v4
|
|
21
|
-
|
|
22
|
-
- name: Setup Node.js ${{ matrix.node-version }}
|
|
23
|
-
uses: actions/setup-node@v4
|
|
24
|
-
with:
|
|
25
|
-
node-version: ${{ matrix.node-version }}
|
|
26
|
-
cache: 'npm'
|
|
27
|
-
|
|
28
|
-
- name: Install dependencies
|
|
29
|
-
run: npm ci
|
|
30
|
-
|
|
31
|
-
- name: Run tests
|
|
32
|
-
run: npm test
|