📄 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