-
Notifications
You must be signed in to change notification settings - Fork 237
Expand file tree
/
Copy pathuser-agent-utils.test.ts
More file actions
317 lines (308 loc) · 14.3 KB
/
user-agent-utils.test.ts
File metadata and controls
317 lines (308 loc) · 14.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
import uaParserDeviceTestCases from './device.test.json'
import { isUndefined } from '@posthog/core'
import uaParserOSTestCases from './os-test.json'
import { detectBrowser, detectBrowserVersion, detectDeviceType, detectOS } from '@posthog/core'
describe('user-agent-utils', () => {
describe('user agent', () => {
// can use https://user-agents.net/ or $raw_user_agent property on events to get new test cases
const browserTestcases: {
name: string
userAgent: string
vendor?: string
expectedVersion: number | null
expectedBrowser: string
}[] = [
{
name: 'Chrome 91 on Windows',
userAgent:
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
vendor: '',
expectedVersion: 91.0,
expectedBrowser: 'Chrome',
},
{
name: 'Chrome 112 on mac',
userAgent:
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36',
expectedVersion: 112.0,
expectedBrowser: 'Chrome',
},
{
name: 'Chrome 111 on Linux',
userAgent:
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36',
expectedVersion: 111.0,
expectedBrowser: 'Chrome',
},
{
name: 'Chrome 16 on Android',
userAgent:
'Mozilla/5.0 (Linux; U; Android-4.0.3; en-us; Galaxy Nexus Build/IML74K) AppleWebKit/535.7 (KHTML, like Gecko) CrMo/16.0.912.75 Mobile Safari/535.7',
expectedVersion: 16.0,
expectedBrowser: 'Chrome',
},
{
name: 'Chrome 21 iOS',
userAgent:
'Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_1_1 like Mac OS X; en) AppleWebKit/534.46.0 (KHTML, like Gecko) CriOS/21.0.1180.82 Mobile/9B206 Safari/7534.48.3',
vendor: '',
expectedVersion: 21.0,
expectedBrowser: 'Chrome iOS',
},
{
name: 'Firefox 89',
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0',
vendor: '',
expectedVersion: 89.0,
expectedBrowser: 'Firefox',
},
{
name: 'unknown browser',
userAgent: 'UnknownBrowser/5.0',
vendor: '',
expectedVersion: null,
expectedBrowser: '',
},
{
name: 'invalid chrome',
userAgent:
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome Safari/537.36',
vendor: '',
expectedVersion: null,
expectedBrowser: 'Chrome',
},
{
name: 'Internet Explorer Mobile',
userAgent:
'Mozilla/5.0 (Windows Phone 8.1; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; 909) like Gecko',
vendor: '',
expectedVersion: 11.0,
expectedBrowser: 'Internet Explorer Mobile',
},
{
name: 'Microsoft Edge 44',
userAgent:
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Edge/44.17763.831.0',
vendor: '',
expectedVersion: 44.17763,
expectedBrowser: 'Microsoft Edge',
},
{
name: 'UC Browser',
userAgent:
'Mozilla/5.0 (Linux; U; Android 4.2.2; en-US; Micromax A116 Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 UCBrowser/10.7.5.658 U3/0.8.0 Mobile Safari/534.30',
vendor: '',
expectedVersion: 10.7,
expectedBrowser: 'UC Browser',
},
{
name: 'Safari',
userAgent:
'Mozilla/5.0 (Macintosh; Intel Mac OS X 14_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1 Safari/605.1.15',
vendor: 'Apple',
expectedVersion: 17.1,
expectedBrowser: 'Safari',
},
{
name: 'Opera',
userAgent:
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.69 Safari/537.36 OPR/34.0.2036.25',
vendor: '',
expectedVersion: 34.0,
expectedBrowser: 'Opera',
},
{
name: 'Firefox iOS',
userAgent:
'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) FxiOS/8.3b5826 Mobile/14E5239e Safari/602.1.50',
vendor: '',
expectedVersion: 8.3,
expectedBrowser: 'Firefox iOS',
},
{
name: 'Konqueror (lowercase)',
userAgent: 'Mozilla/5.0 (X11; U; U; DragonFly amd64) KIO/5.97 konqueror/22.08.0',
vendor: '',
expectedVersion: 22.08,
expectedBrowser: 'Konqueror',
},
{
name: 'Konqueror (uppercase)',
userAgent: 'Mozilla/5.0 (X11; Linux i686) KHTML/5.20 (like Gecko) Konqueror/5.20',
vendor: '',
expectedVersion: 5.2,
expectedBrowser: 'Konqueror',
},
{
name: 'BlackBerry Bold 9790',
userAgent:
'Mozilla/5.0 (BlackBerry; U; BlackBerry 9790; es) AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.1.0.569 Mobile Safari/534.11+',
vendor: '',
// TODO should we match 9790 the model and not 7.1 the browser version?
expectedVersion: 9790,
expectedBrowser: 'BlackBerry',
},
{
name: 'BlackBerry BB10 version v10.1',
userAgent:
'Mozilla/5.0 (BB10; Kbd) AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.1.0.1720 Mobile Safari/537.10+',
vendor: '',
expectedVersion: 10.1,
expectedBrowser: 'BlackBerry',
},
{
name: 'Samsung Internet',
userAgent:
'Mozilla/5.0 (Linux; Android 5.0.2; SAMSUNG SM-T550 Build/LRX22G) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/3.5 Chrome/38.0.2125.102 Safari/537.36',
vendor: '',
expectedVersion: 3.5,
expectedBrowser: 'Samsung Internet',
},
{
name: 'Internet Explorer',
userAgent: 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)',
vendor: '',
expectedVersion: 10.0,
expectedBrowser: 'Internet Explorer',
},
{
name: 'mobile safari (with vendor)',
userAgent:
'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1',
vendor: 'Apple',
expectedVersion: 16.6,
expectedBrowser: 'Mobile Safari',
},
{
name: 'mobile safari (without vendor)',
userAgent:
'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1',
vendor: '', // vendor is deprecated, and we see this user agent not matching in the wild
expectedVersion: 16.6,
expectedBrowser: 'Mobile Safari',
},
{
name: 'firefox for ios',
userAgent:
'Mozilla/5.0 (iPhone; CPU iPhone OS 15_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) FxiOS/106.0 Mobile/15E148 Safari/605.1.15',
vendor: '',
expectedVersion: 106.0,
expectedBrowser: 'Firefox iOS',
},
{
name: 'Android Browser on Galaxy Nexus',
userAgent:
'Mozilla/5.0 (Linux; U; Android 4.0.2; en-us; Galaxy Nexus Build/ICL53F) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',
expectedVersion: 4.0,
expectedBrowser: 'Android Mobile',
},
{
name: 'Chrome Browser on Galaxy S3',
userAgent:
'Mozilla/5.0 (Linux; Android 4.4.4; en-us; SAMSUNG GT-I9300I Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Version/1.5 Chrome/28.0.1500.94 Mobile Safari/537.36',
expectedVersion: 28.0,
expectedBrowser: 'Chrome',
},
]
test.each(browserTestcases)('browser version %s', ({ userAgent, vendor, expectedVersion }) => {
expect(detectBrowserVersion(userAgent, vendor)).toBe(expectedVersion)
})
test.each(browserTestcases)('browser %s', ({ userAgent, vendor, expectedBrowser }) => {
expect(detectBrowser(userAgent, vendor)).toBe(expectedBrowser)
})
/**
* ua-parser-js v1 has MIT licensed test cases
* at "https://github.com/faisalman/ua-parser-js#8087a1b4f0e25f1663ca3ddc2e06371d36642173"
* they were copied here
*/
test.each(uaParserDeviceTestCases.filter((tc) => !tc['//']))('device - $ua', (testCase) => {
if (testCase['expect']['type'] === 'smarttv') {
// we'll test that separately
return
}
if (testCase['expect']['type'] === 'wearable') {
// we'll test that separately
return
}
if (testCase['expect']['type'] === 'embedded') {
// we don't support it
return
}
const actual = detectDeviceType(testCase['ua']).toLowerCase()
const expected =
isUndefined(testCase['expect']['type']) || testCase['expect']['type'] === 'undefined'
? 'desktop'
: testCase['expect']['type']
expect(actual).toBe(expected)
})
/**
* ua-parser-js v1 has MIT licensed test cases
* at "https://github.com/faisalman/ua-parser-js#8087a1b4f0e25f1663ca3ddc2e06371d36642173"
* they were copied here
*
* we had to edit them a chunk because we don't aim for the same level of detail
*/
test.each(uaParserOSTestCases.filter((tc) => !tc['//']))('OS - $ua', (testCase) => {
const result = detectOS(testCase['ua'])
const expected = testCase['expect']
expect(result).toStrictEqual([expected.os_name, expected.os_version])
})
test('can rely on vendor string to detect safari', () => {
const ua = 'Mozilla/5.0 (darwin) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/16.7.0'
const vendor = 'Apple Computer, Inc.'
expect(detectBrowser(ua, vendor)).toBe('Safari')
})
test('osVersion', () => {
const osVersions = {
// Windows Phone
'Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 635; BOOST) like iPhone OS 7_0_3 Mac OS X AppleWebKit/537 (KHTML, like Gecko) Mobile Safari/537':
{ os_name: 'Windows Phone', os_version: '' },
'Mozilla/5.0 (Windows NT 6.3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36':
{
os_name: 'Windows',
os_version: '8.1',
},
'Mozilla/5.0 (iPhone; CPU iPhone OS 8_2 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) CriOS/44.0.2403.67 Mobile/12D508 Safari/600.1.4':
{
os_name: 'iOS',
os_version: '8.2.0',
},
'Mozilla/5.0 (iPad; CPU OS 8_4 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12H143 Safari/600.1.4':
{
os_name: 'iOS',
os_version: '8.4.0',
},
'Mozilla/5.0 (Linux; Android 4.4.2; Lenovo A7600-F Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.133 Safari/537.36':
{
os_name: 'Android',
os_version: '4.4.2',
},
'Mozilla/5.0 (BlackBerry; U; BlackBerry 9300; es) AppleWebKit/534.8+ (KHTML, like Gecko) Version/6.0.0.480 Mobile Safari/534.8+':
{
os_name: 'BlackBerry',
os_version: '',
},
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.130 Safari/537.36':
{
os_name: 'Mac OS X',
os_version: '10.9.5',
},
'Opera/9.80 (Linux armv7l; InettvBrowser/2.2 (00014A;SonyDTV140;0001;0001) KDL40W600B; CC/MEX) Presto/2.12.407 Version/12.50':
{
os_name: 'Linux',
os_version: '',
},
'Mozilla/5.0 (X11; CrOS armv7l 6680.81.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36':
{
os_name: 'Chrome OS',
os_version: '',
},
}
for (const [userAgent, osInfo] of Object.entries(osVersions)) {
const [os_name, os_version] = detectOS(userAgent)
expect(os_name).toBe(osInfo.os_name)
expect(os_version).toBe(osInfo.os_version)
}
})
})
})