📄 src/web3/wallet/browsers.test.ts
D-OPEN SOVEREIGN
1import { describe, it, expect } from 'vitest';
2import { parseUserAgent, Browser, Platform } from './browsers';
3
4const UA = {
5 chromeWindows: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36',
6 firefoxWindows: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0',
7 safariMac: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Safari/605.1.15',
8 edgeWindows: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.183',
9 operaWindows: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 OPR/100.0.0.0',
10 braveDesktop: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Brave/1.55',
11 vivaldiDesktop: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Vivaldi/6.1',
12 yandexDesktop: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 YaBrowser/23.7.0.0',
13 chromeAndroid: 'Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Mobile Safari/537.36',
14 safariIphone: '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',
15 safariIpad: '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',
16};
17
18describe('parseUserAgent: browser detection', () => {
19 it('detects Chrome', () => {
20 expect(parseUserAgent(UA.chromeWindows).browser).toBe(Browser.chromium);
21 });
22
23 it('detects Firefox', () => {
24 expect(parseUserAgent(UA.firefoxWindows).browser).toBe(Browser.firefox);
25 });
26
27 it('detects Safari and does not confuse it with Chrome despite sharing the "Safari/" token', () => {
28 expect(parseUserAgent(UA.safariMac).browser).toBe(Browser.safari);
29 });
30
31 it('detects Edge even though its UA also contains Chrome/Safari tokens', () => {
32 expect(parseUserAgent(UA.edgeWindows).browser).toBe(Browser.edge);
33 });
34
35 it('detects Opera even though its UA also contains Chrome/Safari tokens', () => {
36 expect(parseUserAgent(UA.operaWindows).browser).toBe(Browser.opera);
37 });
38
39 it('detects Brave when its UA self-identifies (real Brave UAs normally omit this by design)', () => {
40 expect(parseUserAgent(UA.braveDesktop).browser).toBe(Browser.brave);
41 });
42
43 it('detects Vivaldi', () => {
44 expect(parseUserAgent(UA.vivaldiDesktop).browser).toBe(Browser.vivaldi);
45 });
46
47 it('detects a real Yandex Browser UA via its actual "YaBrowser/" token (fixed)', () => {
48 // Regression test: real Yandex Browser UAs self-identify as "YaBrowser/"
49 // (e.g. "...Chrome/113.0.0.0 YaBrowser/23.7.0.0 Safari/537.36"), never
50 // containing the literal word "yandex".
51 expect(parseUserAgent(UA.yandexDesktop).browser).toBe(Browser.yandex);
52 });
53
54 it('is case-insensitive', () => {
55 expect(parseUserAgent(UA.firefoxWindows.toUpperCase()).browser).toBe(Browser.firefox);
56 });
57
58 it('defaults to chromium for an empty or unrecognized UA string', () => {
59 expect(parseUserAgent('').browser).toBe(Browser.chromium);
60 expect(parseUserAgent('some totally unknown client/1.0').browser).toBe(Browser.chromium);
61 });
62
63 it('defaults to navigator.userAgent when no argument is given, or "" outside a browser', () => {
64 // In this (Node) test environment there is no `navigator`, so the default
65 // parameter evaluates to ''.
66 const result = parseUserAgent();
67 expect(result.browser).toBe(Browser.chromium);
68 expect(result.platform).toBe(Platform.browsers);
69 });
70});
71
72describe('parseUserAgent: platform detection', () => {
73 it('detects Android', () => {
74 expect(parseUserAgent(UA.chromeAndroid).platform).toBe(Platform.android);
75 });
76
77 it('detects iOS for iPhone', () => {
78 expect(parseUserAgent(UA.safariIphone).platform).toBe(Platform.ios);
79 });
80
81 it('detects iOS for iPad', () => {
82 expect(parseUserAgent(UA.safariIpad).platform).toBe(Platform.ios);
83 });
84
85 it('defaults to "browsers" for desktop UAs', () => {
86 expect(parseUserAgent(UA.chromeWindows).platform).toBe(Platform.browsers);
87 });
88});
89