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.
@@ -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
- Object.defineProperty(window, 'location', {
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
- // Arrange
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
- // Test 127.0.0.1
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
- // Test non-localhost
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') // Should use navigator.language as fallback
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('getPath should handle different URL formats', () => {
120
- // Arrange
121
- Object.defineProperty(window, 'location', {
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
- // Act & Assert - basic path
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
- // Test with hash
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
- // Test with search
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
- // Test with both hash and search
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
- // Test with search in hash
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
- // Arrange
180
- Object.defineProperty(window, 'location', {
181
- value: {
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
- // Test with 'ref' and 'source' parameters as well
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
- Object.defineProperty(window, 'location', {
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
  })
@@ -1,2 +0,0 @@
1
- github: swetrix
2
- ko_fi: andriir
@@ -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