From b0b0673bec554775421d1c86e3dbe6b85be34332 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20S=C3=A1nchez?= Date: Fri, 13 Oct 2023 14:29:05 +0200 Subject: [PATCH] fix: change server info (#9) * fix: change server info * chore: update * chore: remove version from server info (included todo) --- README.md | 10 ++- browser-test/browser.test.ts | 4 ++ package.json | 7 +- pnpm-lock.yaml | 68 ++++++++++---------- src/index.ts | 63 ++++++++++++++---- test/browser-detection.test.ts | 114 ++++++++++++++++----------------- test/node.test.ts | 19 ------ test/server.test.ts | 28 ++++++++ tsconfig.json | 2 +- 9 files changed, 182 insertions(+), 133 deletions(-) delete mode 100644 test/node.test.ts create mode 100644 test/server.test.ts diff --git a/README.md b/README.md index 32d354f..4d9efe0 100644 --- a/README.md +++ b/README.md @@ -30,16 +30,14 @@ import { detect } from 'detect-browser-es' const { detect } = require('detect-browser-es') ``` -## Breaking Changes +## Deprecations -**TODO**: maybe we can revert these changes before releasing the first version. - -[NodeInfo](https://github.com/DamonOehlman/detect-browser/blob/master/src/index.ts#L30) and [getNodeVersion](https://github.com/DamonOehlman/detect-browser/blob/master/src/index.ts#L306C17-L306C31) have been renamed to [ServerInfo](https://github.com/userquin/detect-browser-es/blob/main/src/index.ts#L47) and [getServerVersion](https://github.com/userquin/detect-browser-es/blob/main/src/index.ts#L366) respectively. +[NodeInfo](https://github.com/DamonOehlman/detect-browser/blob/master/src/index.ts#L30) and [getNodeVersion](https://github.com/DamonOehlman/detect-browser/blob/master/src/index.ts#L306C17-L306C31) have been deprecated and replaced with [ServerInfo](https://github.com/userquin/detect-browser-es/blob/main/src/index.ts#L47) and [getServerVersion](https://github.com/userquin/detect-browser-es/blob/main/src/index.ts#L366) respectively. ## New Features - Detect [Happy DOM](https://github.com/capricorn86/happy-dom) and [jsdom](https://github.com/jsdom/jsdom) when using test environments like [Vitest](https://github.com/vitest-dev/vitest) (check the [test](https://github.com/userquin/detect-browser-es/tree/main/test) folder). -- Detect [WebdriverIO](https://github.com/webdriverio/webdriverio) when using WebdriverIO tests or test environments like [Vitest](https://github.com/vitest-dev/vitest) with `@vitest/browser`. +- Detect [WebdriverIO](https://github.com/webdriverio/webdriverio) when using WebdriverIO tests. - ServerInfo via [std-env](https://github.com/unjs/std-env) with [provider](https://github.com/unjs/std-env#provider-detection) and [runtime](https://github.com/unjs/std-env#runtime-detection) detection. ## Testing @@ -48,7 +46,7 @@ To run the tests, from root folder run `nr test`, the script will run: - the original tests from `detect-browser` - Happy DOM and jsdom tests, except WebdriverIO detection -To test WebdriverIO detection, run one of the following commands (requires Vitest v1.0.0-beta.2, not yet released, tests will not work): +To test WebdriverIO detection, run one of the following commands: - `nr wdio-chrome`: Chrome must be installed - `nr wdio-edge`: Edge must be installed - `nr wdio-firefox`: Firefox must be installed diff --git a/browser-test/browser.test.ts b/browser-test/browser.test.ts index 0722001..6053ca9 100644 --- a/browser-test/browser.test.ts +++ b/browser-test/browser.test.ts @@ -10,6 +10,10 @@ describe('Browser Detection test', () => { expect(typeof navigator).toBeDefined() expect(typeof navigator?.userAgent).toBeDefined() }) + // TODO: missing __wdioSpec__ and cookie + test.skip('WebdriverIO Detection', () => { + expect(detect()?.type).toBe('webdriverio') + }) test.skipIf(browser !== 'chrome')('Chrome', () => { expect(detect()?.name).toBe('chrome') }) diff --git a/package.json b/package.json index 1bb99a3..e524c24 100644 --- a/package.json +++ b/package.json @@ -37,8 +37,7 @@ "wdio-chrome": "BROWSER=chrome vitest --c vitest-browser.config.mts", "wdio-edge": "BROWSER=edge vitest --c vitest-browser.config.mts", "wdio-firefox": "BROWSER=firefox vitest --c vitest-browser.config.mts", - "wdio-safari": "BROWSER=safari vitest --c vitest-browser.config.mts", - "wdio-test": "pnpm run wdio-chrome && pnpm run wdio-edge && pnpm run wdio-firefox" + "wdio-safari": "BROWSER=safari vitest --c vitest-browser.config.mts" }, "dependencies": { "std-env": "^3.4.3" @@ -48,7 +47,7 @@ "@antfu/ni": "^0.21.8", "@types/node": "^18.18.4", "@typescript-eslint/eslint-plugin": "^6.6.0", - "@vitest/browser": "^1.0.0-beta.1", + "@vitest/browser": "^1.0.0-beta.2", "@vitest/coverage-v8": "^0.34.6", "@vitest/utils": "^0.34.6", "bumpp": "^9.2.0", @@ -57,7 +56,7 @@ "jsdom": "^22.1.0", "typescript": "^5.2.2", "unbuild": "^1.2.1", - "vitest": "^1.0.0-beta.1", + "vitest": "^1.0.0-beta.2", "webdriverio": "^8.18.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b021dbb..f80003d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,11 +23,11 @@ devDependencies: specifier: ^6.6.0 version: 6.7.5(@typescript-eslint/parser@6.7.5)(eslint@8.51.0)(typescript@5.2.2) '@vitest/browser': - specifier: ^1.0.0-beta.1 - version: 1.0.0-beta.1(vitest@1.0.0-beta.1) + specifier: ^1.0.0-beta.2 + version: 1.0.0-beta.2(vitest@1.0.0-beta.2) '@vitest/coverage-v8': specifier: ^0.34.6 - version: 0.34.6(vitest@1.0.0-beta.1) + version: 0.34.6(vitest@1.0.0-beta.2) '@vitest/utils': specifier: ^0.34.6 version: 0.34.6 @@ -50,8 +50,8 @@ devDependencies: specifier: ^1.2.1 version: 1.2.1 vitest: - specifier: ^1.0.0-beta.1 - version: 1.0.0-beta.1(@types/node@18.18.4)(@vitest/browser@1.0.0-beta.1)(happy-dom@12.9.1)(jsdom@22.1.0)(webdriverio@8.18.0) + specifier: ^1.0.0-beta.2 + version: 1.0.0-beta.2(@types/node@18.18.4)(@vitest/browser@1.0.0-beta.2)(happy-dom@12.9.1)(jsdom@22.1.0)(webdriverio@8.18.0) webdriverio: specifier: ^8.18.0 version: 8.18.0(typescript@5.2.2) @@ -1375,18 +1375,18 @@ packages: eslint-visitor-keys: 3.4.3 dev: true - /@vitest/browser@1.0.0-beta.1(vitest@1.0.0-beta.1): - resolution: {integrity: sha512-R01YjYfC4S7wNdz2dcA3n9xGx9XevDx+T5ejGUoQzE5PP5kHzuHHyiH9urK0+oJjB0+PCu4UaU/abrvdVU7idQ==} + /@vitest/browser@1.0.0-beta.2(vitest@1.0.0-beta.2): + resolution: {integrity: sha512-beaLqkoBmC8LWhPfDKn8pTUi/uXX95mgsku583EhF3d4WBZhpc154CPSR6bbz7JaMqCoBtoiTaFTcZ8Zpu6cmw==} peerDependencies: vitest: '>=0.34.0' dependencies: estree-walker: 3.0.3 magic-string: 0.30.4 sirv: 2.0.3 - vitest: 1.0.0-beta.1(@types/node@18.18.4)(@vitest/browser@1.0.0-beta.1)(happy-dom@12.9.1)(jsdom@22.1.0)(webdriverio@8.18.0) + vitest: 1.0.0-beta.2(@types/node@18.18.4)(@vitest/browser@1.0.0-beta.2)(happy-dom@12.9.1)(jsdom@22.1.0)(webdriverio@8.18.0) dev: true - /@vitest/coverage-v8@0.34.6(vitest@1.0.0-beta.1): + /@vitest/coverage-v8@0.34.6(vitest@1.0.0-beta.2): resolution: {integrity: sha512-fivy/OK2d/EsJFoEoxHFEnNGTg+MmdZBAVK9Ka4qhXR2K3J0DS08vcGVwzDtXSuUMabLv4KtPcpSKkcMXFDViw==} peerDependencies: vitest: '>=0.32.0 <1' @@ -1402,37 +1402,37 @@ packages: std-env: 3.4.3 test-exclude: 6.0.0 v8-to-istanbul: 9.1.3 - vitest: 1.0.0-beta.1(@types/node@18.18.4)(@vitest/browser@1.0.0-beta.1)(happy-dom@12.9.1)(jsdom@22.1.0)(webdriverio@8.18.0) + vitest: 1.0.0-beta.2(@types/node@18.18.4)(@vitest/browser@1.0.0-beta.2)(happy-dom@12.9.1)(jsdom@22.1.0)(webdriverio@8.18.0) transitivePeerDependencies: - supports-color dev: true - /@vitest/expect@1.0.0-beta.1: - resolution: {integrity: sha512-FgpctOcKcHuroFgO5JMOpjk2F0YZvWH1cBPagoQcr0ckJUq3/V7udPxw7w/dBeyn/zqyhGfOzY4z9jLHaEbCqw==} + /@vitest/expect@1.0.0-beta.2: + resolution: {integrity: sha512-u3CoUMNn+0SxGzqLC4hdbyoCACduaBmM2AcGWpqdweM7CS8PxfDhbbuhClLmLg7OOd1RjFAGO09x5iWQjX+Rmw==} dependencies: - '@vitest/spy': 1.0.0-beta.1 - '@vitest/utils': 1.0.0-beta.1 + '@vitest/spy': 1.0.0-beta.2 + '@vitest/utils': 1.0.0-beta.2 chai: 4.3.10 dev: true - /@vitest/runner@1.0.0-beta.1: - resolution: {integrity: sha512-TbZs0A58pNwELRseqkr//OmNy+8G027Lq1emqibMZ+jmDFd5d0QAWafwbNBXswhiYYZQxnQlcJPndkVyAsqP4g==} + /@vitest/runner@1.0.0-beta.2: + resolution: {integrity: sha512-+W59xEwQg8re9kQOitAYgjjO6LBkPgyUIhCryEslfxwFYJZC3+4CPIJI/8Wac53cUR0NcXzraF8mplE5JYIptQ==} dependencies: - '@vitest/utils': 1.0.0-beta.1 + '@vitest/utils': 1.0.0-beta.2 p-limit: 4.0.0 pathe: 1.1.1 dev: true - /@vitest/snapshot@1.0.0-beta.1: - resolution: {integrity: sha512-3ZBkBJ7O0zLvvAdARD56Srfdk/sgROdBFCUnayGv1/L4ZkwB4GRRl+zuZdT/GhNDT1Q0NMBntbwyIrCSASpY/A==} + /@vitest/snapshot@1.0.0-beta.2: + resolution: {integrity: sha512-ldL0EnnFr8Pkh7j+sY6ffWXN6UlQCEmMxvxaq/REgf7SKy09L2aJtqnTH3PvcCt98JqOESrd1UpcCRvQml5gVw==} dependencies: magic-string: 0.30.4 pathe: 1.1.1 pretty-format: 29.7.0 dev: true - /@vitest/spy@1.0.0-beta.1: - resolution: {integrity: sha512-oRUzAGwIVRxrIy/0HZHPEkftcTDWlgBk1tR5yBywOewUZTtoXACCpaaht4sY/DExcPbrsROhrJB4vw0d2Jittw==} + /@vitest/spy@1.0.0-beta.2: + resolution: {integrity: sha512-mamPkcuSa2RtOfZnYOayLT8UAOd9/ok3TFKzGemir2rUYK0abjKGjMhKx9A6MXGHI7yeyrHbAdK3p9BeP6lS7g==} dependencies: tinyspy: 2.2.0 dev: true @@ -1445,8 +1445,8 @@ packages: pretty-format: 29.7.0 dev: true - /@vitest/utils@1.0.0-beta.1: - resolution: {integrity: sha512-jfcqEzZamUA2Th76NVOHyRMAUIAuxMG9q+BstUbxzPQ9IkbCjz5GkhagPfy4r6zTFiElhX7mmPVj/nvB/Ea/bQ==} + /@vitest/utils@1.0.0-beta.2: + resolution: {integrity: sha512-l5SWv83I91FYcJ9/dWLDmhacvl0LSVn4ATM9OcJNVxbx/P8YaTPPY93MI6OWLazTOdbFPOIDno+c9qIvxBTZ+Q==} dependencies: diff-sequences: 29.6.3 loupe: 2.3.6 @@ -5280,8 +5280,8 @@ packages: spdx-expression-parse: 3.0.1 dev: true - /vite-node@1.0.0-beta.1(@types/node@18.18.4): - resolution: {integrity: sha512-ArgMpx8elnnDsU6cKIu9GtUIz2xrL2okVErc5J+znVytA6yb6K1AVFxKpxUuwSUcyw+CD5+xZwOdZRbjC+TUiQ==} + /vite-node@1.0.0-beta.2(@types/node@18.18.4): + resolution: {integrity: sha512-UMkLLjX8HYsSyTKWVVF4AMBtRpp1UmEB5fxJSWzUlNYoCAbmIB24nd/VAG5ZwZQXS8HpBDHdU6XihreXIu1FXA==} engines: {node: '>=v14.18.0'} hasBin: true dependencies: @@ -5338,8 +5338,8 @@ packages: fsevents: 2.3.3 dev: true - /vitest@1.0.0-beta.1(@types/node@18.18.4)(@vitest/browser@1.0.0-beta.1)(happy-dom@12.9.1)(jsdom@22.1.0)(webdriverio@8.18.0): - resolution: {integrity: sha512-0COrNeOzBmcynWKjnrZ70Vy6BbdcFsKZmqvhjt2PM3ZF1KgprSShNIFFVKthqPj5GjgUbXUR8rFjOAWzTYPd/g==} + /vitest@1.0.0-beta.2(@types/node@18.18.4)(@vitest/browser@1.0.0-beta.2)(happy-dom@12.9.1)(jsdom@22.1.0)(webdriverio@8.18.0): + resolution: {integrity: sha512-jWQGjTETEz1OF7TST3iUOPL+Te1IgVfrSvFr+bu5pYIhcmSOmFUnQZ91ffOy7MUqlgaxHehAOhmaCtjde0u5CQ==} engines: {node: '>=v14.18.0'} hasBin: true peerDependencies: @@ -5373,12 +5373,12 @@ packages: optional: true dependencies: '@types/node': 18.18.4 - '@vitest/browser': 1.0.0-beta.1(vitest@1.0.0-beta.1) - '@vitest/expect': 1.0.0-beta.1 - '@vitest/runner': 1.0.0-beta.1 - '@vitest/snapshot': 1.0.0-beta.1 - '@vitest/spy': 1.0.0-beta.1 - '@vitest/utils': 1.0.0-beta.1 + '@vitest/browser': 1.0.0-beta.2(vitest@1.0.0-beta.2) + '@vitest/expect': 1.0.0-beta.2 + '@vitest/runner': 1.0.0-beta.2 + '@vitest/snapshot': 1.0.0-beta.2 + '@vitest/spy': 1.0.0-beta.2 + '@vitest/utils': 1.0.0-beta.2 acorn: 8.10.0 acorn-walk: 8.2.0 cac: 6.7.14 @@ -5395,7 +5395,7 @@ packages: tinybench: 2.5.1 tinypool: 0.8.1 vite: 4.4.11(@types/node@18.18.4) - vite-node: 1.0.0-beta.1(@types/node@18.18.4) + vite-node: 1.0.0-beta.2(@types/node@18.18.4) webdriverio: 8.18.0(typescript@5.2.2) why-is-node-running: 2.2.2 transitivePeerDependencies: diff --git a/src/index.ts b/src/index.ts index cc587e9..41e6571 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,22 +1,25 @@ import { - type ProviderInfo, - type RuntimeInfo, nodeMajorVersion, nodeVersion, platform, providerInfo, - runtimeInfo, + runtime, runtimeInfo, +} from 'std-env' +import type { + ProviderInfo, + RuntimeInfo, + RuntimeName, } from 'std-env' export type DetectedInfoType = | 'browser' - | 'node' | 'jsdom' | 'happy-dom' | 'webdriverio' | 'bot-device' | 'bot' | 'react-native' + | RuntimeName interface DetectedInfo< T extends DetectedInfoType, N extends string, O, V = null, @@ -45,17 +48,35 @@ implements DetectedInfo<'browser', Browser, OperatingSystem | null, string> { ) {} } -export class ServerInfo +/** + * @deprecated Use `ServerInfo` instead + */ +export class NodeInfo implements DetectedInfo<'node', 'node', NodeJS.Platform, string> { public readonly type = 'node' public readonly name: 'node' = 'node' as const public readonly os: NodeJS.Platform = platform + + constructor(public readonly version: string) {} +} + +// TODO: include version if possible +export class ServerInfo +implements DetectedInfo { public readonly nodeVersion: string | null = nodeVersion public readonly nodeMajorVersion: number | null = nodeMajorVersion public readonly provider: ProviderInfo | undefined = providerInfo public readonly runtime: RuntimeInfo | undefined = runtimeInfo + // TODO: include version if possible + public readonly version: null = null - constructor(public readonly version: string) {} + constructor( + public readonly name: RuntimeName, + public readonly type: RuntimeName, + public readonly os: ProviderInfo, + // TODO: include version if possible + // public readonly version: string, + ) {} } export class SearchBotDeviceInfo @@ -70,7 +91,7 @@ implements ) {} } -export class BotInfo implements DetectedInfo<'bot', 'bot', null, null> { +export class BotInfo implements DetectedInfo<'bot', 'bot', null> { public readonly type = 'bot' public readonly bot: true = true as const // NOTE: deprecated test name instead public readonly name: 'bot' = 'bot' as const @@ -79,7 +100,7 @@ export class BotInfo implements DetectedInfo<'bot', 'bot', null, null> { } export class ReactNativeInfo -implements DetectedInfo<'react-native', 'react-native', null, null> { +implements DetectedInfo<'react-native', 'react-native', null> { public readonly type = 'react-native' public readonly name: 'react-native' = 'react-native' as const public readonly version: null = null @@ -106,7 +127,7 @@ implements DetectedInfo<'happy-dom', Browser, OperatingSystem | null, string> { ) {} } -export class WebDriverIOInfo +export class WebdriverIOInfo implements DetectedInfo<'webdriverio', Browser, OperatingSystem | null, string> { public readonly type = 'webdriverio' constructor( @@ -149,7 +170,6 @@ export type Browser = | 'searchbot' | 'jsdom' | 'happy-dom' - | 'webdriverio' export type OperatingSystem = | 'iOS' | 'Android OS' @@ -290,7 +310,7 @@ export function detect(userAgent?: string) { if ('__wdioSpec__' in window) { const browser = parseUserAgent(navigator.userAgent) if (browser instanceof BrowserInfo) - return new WebDriverIOInfo(browser.name, browser.version, browser.os) + return new WebdriverIOInfo(browser.name, browser.version, browser.os) } } @@ -371,11 +391,30 @@ export function detectOS(ua: string) { return null } +/** + * @deprecated Use `getServerVersion` instead + */ +export function getNodeVersion() { + if (runtime !== 'node' || !nodeVersion) + return null + + return new NodeInfo(nodeVersion) +} + export function getServerVersion() { - return nodeVersion ? new ServerInfo(`${nodeVersion}`) : null + // TODO: how to extract version? + return runtimeInfo + ? new ServerInfo( + runtimeInfo.name, + runtimeInfo.name, + providerInfo, + // TODO: include version if possible + ) + : null } function createVersionParts(count: number) { + // return Array.from({ length: count }, () => '0') const output: string[] = [] for (let ii = 0; ii < count; ii++) output.push('0') diff --git a/test/browser-detection.test.ts b/test/browser-detection.test.ts index 7807d39..1500a37 100644 --- a/test/browser-detection.test.ts +++ b/test/browser-detection.test.ts @@ -120,56 +120,56 @@ describe('browser detection', () => { }) // original detect-browser tests test('detects chrome', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36', )).toEqual({ type: 'browser', name: 'chrome', version: '50.0.2661', os: 'Linux' }) - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36', )).toEqual({ type: 'browser', name: 'chrome', version: '41.0.2228', os: 'Windows 7' }) - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36', )).toEqual({ type: 'browser', name: 'chrome', version: '72.0.3626', os: 'Windows 10' }) }) test('detects Chrome for iOS', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_1_1 like Mac OS X; en) AppleWebKit/534.46.0 (KHTML, like Gecko) CriOS/19.0.1084.60 Mobile/9B206 Safari/7534.48.3', )).toEqual({ type: 'browser', name: 'crios', version: '19.0.1084', os: 'iOS' }) }) test('detects Firefox', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:46.0) Gecko/20100101 Firefox/46.0', )).toEqual({ type: 'browser', name: 'firefox', version: '46.0.0', os: 'Linux' }) - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1', )).toEqual({ type: 'browser', name: 'firefox', version: '40.1.0', os: 'Windows 7' }) }) test('detects Firefox for iOS', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (iPad; CPU iPhone OS 8_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) FxiOS/1.0 Mobile/12F69 Safari/600.1.4', )).toEqual({ type: 'browser', name: 'fxios', version: '1.0.0', os: 'iOS' }) - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (iPad; CPU iPhone OS 8_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) FxiOS/3.2 Mobile/12F69 Safari/600.1.4', )).toEqual({ type: 'browser', name: 'fxios', version: '3.2.0', os: 'iOS' }) }) test('detects Edge', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.246', )).toEqual({ type: 'browser', name: 'edge', version: '12.246.0', os: 'Windows 10' }) - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (Windows NT 6.3; Win64, x64; Touch) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36 Edge/12.0 (Touch; Trident/7.0; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729; HPNTDFJS; H9P; InfoPath', )).toEqual({ type: 'browser', name: 'edge', version: '12.0.0', os: 'Windows 8.1' }) }) test('detects IE', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; .NET4.0E; .NET4.0C; rv:11.0) like Gecko', )).toEqual({ type: 'browser', name: 'ie', version: '11.0.0', os: 'Windows 8.1' }) - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0; MSN 11.61; MSNbMSNI; MSNmen-us; MSNcOTH) like Gecko', )).toEqual({ type: 'browser', name: 'ie', version: '11.0.0', os: 'Windows 10' }) - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (compatible; MSIE 10.6; Windows NT 6.1; Trident/5.0; InfoPath.2; SLCC1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 2.0.50727) 3gpp-gba UNTRUSTED/1.0', )).toEqual({ type: 'browser', name: 'ie', version: '10.6.0', os: 'Windows 7' }) - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 5.2; WOW64; .NET CLR 2.0.50727)', )).toEqual({ type: 'browser', @@ -179,10 +179,10 @@ describe('browser detection', () => { }) }) test('detects Opera', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Opera/9.80 (J2ME/MIDP; Opera Mini/5.0 (Windows; U; Windows NT 5.1; en) AppleWebKit/886; U; en) Presto/2.4.15', )).toEqual({ type: 'browser', name: 'opera', version: '9.80.0', os: 'Windows XP' }) - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Opera/9.25 (Macintosh; Intel Mac OS X; U; en)', )).toEqual({ type: 'browser', @@ -190,38 +190,38 @@ describe('browser detection', () => { version: '9.25.0', os: 'Mac OS', }) - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.84 Safari/537.36 OPR/38.0.2220.31', )).toEqual({ type: 'browser', name: 'opera', version: '38.0.2220', os: 'Mac OS' }) - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.28 Safari/537.36 OPR/61.0.3282.0 (Edition developer)', )).toEqual({ type: 'browser', name: 'opera', version: '61.0.3282', os: 'Mac OS' }) }) test('detects BlackBerry 10', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/7.2.0.0 Mobile Safari/537.10+', )).toEqual({ type: 'browser', name: 'bb10', version: '7.2.0', os: 'BlackBerry OS' }) }) test('detects Android Webkit browser', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (Linux; U; Android 4.0.3; ko-kr; LG-L160L Build/IML74K) AppleWebkit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30', )).toEqual({ type: 'browser', name: 'android', version: '4.0.3', os: 'Android OS' }) }) test('detects mobile Safari', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.25', )).toEqual({ type: 'browser', name: 'ios', version: '6.0.0', os: 'iOS' }) - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (iPod; U; CPU iPhone OS 4_3_3 like Mac OS X; ja-jp) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5', )).toEqual({ type: 'browser', name: 'ios', version: '5.0.2', os: 'iOS' }) }) test('detects Safari', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/7046A194A', )).toEqual({ type: 'browser', name: 'safari', version: '7.0.3', os: 'Mac OS' }) }) test('detects Yandex Browser', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 YaBrowser/16.10.0.2774 Safari/537.36', )).toEqual({ type: 'browser', @@ -231,69 +231,69 @@ describe('browser detection', () => { }) }) test('detects Kakaotalk Browser', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Netscape 5.0 (iPhone; CPU iPhone OS 10_3 1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Mobile/14E304 KAKAOTALK 6.2.2', )).toEqual({ type: 'browser', name: 'kakaotalk', version: '6.2.2', os: 'iOS' }) - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 1 like Mac OS X) AppleWebKit/ 603.1.30 (KHTML, like Gecko) Mobile/ 14E304 KAKAOTALK 6.2.2', )).toEqual({ type: 'browser', name: 'kakaotalk', version: '6.2.2', os: 'iOS' }) }) test('detects PhantomJS Browser', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (Macintosh; Intel Mac OS X) AppleWebKit/538.1 (KHTML, like Gecko) PhantomJS/2.1.1 Safari/538.1', )).toEqual({ type: 'browser', name: 'phantomjs', version: '2.1.1', os: 'Mac OS' }) }) test('detects AOLShield Browser', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2841.00 Safari/537.36 AOLShield/54.0.2848.0', )).toEqual({ type: 'browser', name: 'aol', version: '54.0.2848', os: 'Windows 10' }) }) test('detects facebook in-app browser', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_2_5 like Mac OS X) AppleWebKit/604.5.6 (KHTML, like Gecko) Mobile/15D60 [FBAN/FBIOS;FBAV/157.0.0.42.96;FBBV/90008621;FBDV/iPhone9,1;FBMD/iPhone;FBSN/iOS;FBSV/11.2.5;FBSS/2;FBCR/Verizon;FBID/phone;FBLC/en_US;FBOP/5;FBRV/0]', )).toEqual({ type: 'browser', name: 'facebook', version: '157.0.0', os: 'iOS' }) }) test('detects instagram in-app browser', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_2 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Mobile/13F69 Instagram 8.4.0 (iPhone7,2; iPhone OS 9_3_2; nb_NO; nb-NO; scale=2.00; 750x1334', )).toEqual({ type: 'browser', name: 'instagram', version: '8.4.0', os: 'iOS' }) }) test('detects native iOS WebView browser', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'User-Agent: Mozilla/5.0 (iPad; U; CPU OS 4_3_2 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Mobile', )).toEqual({ type: 'browser', name: 'ios-webview', version: '533.17.9', os: 'iOS' }) - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (iPad; CPU OS 11_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E216', )).toEqual({ type: 'browser', name: 'ios-webview', version: '605.1.15', os: 'iOS' }) - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (iPhone; CPU iPhone OS 12_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/16B92', )).toEqual({ type: 'browser', name: 'ios-webview', version: '605.1.15', os: 'iOS' }) - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (iPhone; CPU iPhone OS 12_1_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko)', )).toEqual({ type: 'browser', name: 'ios-webview', version: '605.1.15', os: 'iOS' }) }) test('detects Samsung Internet browser', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (Linux; Android 5.0.2; SAMSUNG SM-G925F Build/LRX22G) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/4.0 Chrome/44.0.2403.133 Mobile Safari/537.36', )).toEqual({ type: 'browser', name: 'samsung', version: '4.0.0', os: 'Android OS' }) }) test('detects crawler: AhrefsBot', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (compatible; AhrefsBot/5.2; +http://ahrefs.com/robot/)', )).toEqual({ type: 'bot', bot: true, name: 'bot', version: null, os: null }) }) test('detects crawler: GoogleBot', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Googlebot/2.1; +http://www.google.com/bot.html) Safari/537.36', )).toEqual({ type: 'bot', bot: true, name: 'bot', version: null, os: null }) }) test('detects crawler: YandexBot', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)', )).toEqual({ type: 'bot', bot: true, name: 'bot', version: null, os: null }) }) test('detects crawler: YandexBotdetects Opera-Mini', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Opera/9.80 (Android; Opera Mini/8.0.1807/36.1609; U; en) Presto/2.12.423 Version/12.16', )).toEqual({ type: 'browser', @@ -301,7 +301,7 @@ describe('browser detection', () => { version: '12.16.0', os: 'Android OS', }) - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Opera/9.80 (BlackBerry; Opera Mini/6.5.27548/27.2020; U; en) Presto/2.8.119 Version/11.10', )).toEqual({ type: 'browser', @@ -311,36 +311,36 @@ describe('browser detection', () => { }) }) test('detects Silk', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (Linux; Android 4.4.3; KFTHWI Build/KTU84M) AppleWebKit/537.36 (KHTML, like Gecko) Silk/44.1.54 like Chrome/44.0.2403.63 Safari/537.36', )).toEqual({ type: 'browser', name: 'silk', version: '44.1.54', os: 'Android OS' }) - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Silk/44.1.54 like Chrome/44.0.2403.63 Safari/537.36', )).toEqual({ type: 'browser', name: 'silk', version: '44.1.54', os: 'Linux' }) - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (Linux; U; Android 4.4.3; KFTHWI Build/KTU84M) AppleWebKit/537.36 (KHTML, like Gecko) Silk/44.1.54 like Chrome/44.0.2403.63 Mobile Safari/537.36', )).toEqual({ type: 'browser', name: 'silk', version: '44.1.54', os: 'Android OS' }) }) test('detects Chrome OS', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (X11; CrOS x86_64 10895.78.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.120 Safari/537.36', )).toEqual({ type: 'browser', name: 'chrome', version: '69.0.3497', os: 'Chrome OS' }) - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (X11; U; CrOS i686 9.10.0; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Gecko/20100101 Firefox/29.0', )).toEqual({ type: 'browser', name: 'firefox', version: '29.0.0', os: 'Chrome OS' }) }) test('detects miui', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (Linux; U; Android 7.0; en-us; MI 5 Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/53.0.2785.146 Mobile Safari/537.36 XiaoMi/MiuiBrowser/9.0.3', )).toEqual({ type: 'browser', name: 'miui', version: '9.0.3', os: 'Android OS' }) }) test('detects Beaker Browser', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) BeakerBrowser/0.8.7 Chrome/69.0.3497.128 Electron/4.1.3 Safari/537.36', )).toEqual({ type: 'browser', name: 'beaker', version: '0.8.7', os: 'Windows 10' }) }) test('detects edge chromium', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.48 Safari/537.36 Edg/74.1.96.24', )).toEqual({ type: 'browser', @@ -350,7 +350,7 @@ describe('browser detection', () => { }) }) test('detects edge chromium (android os)', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (Linux; Android 9; SM-N950F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.116 Mobile Safari/537.36 EdgA/45.08.4.5074', )).toEqual({ type: 'browser', @@ -360,18 +360,18 @@ describe('browser detection', () => { }) }) test('detects edge iOS', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (iPhone; CPU iPhone OS 12_1_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 EdgiOS/44.2.1 Mobile/16D57 Safari/605.1.15', )).toEqual({ type: 'browser', name: 'edge-ios', version: '44.2.1', os: 'iOS' }) }) test('handles no browser', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( undefined!, )).toBeNull() }) /* https://developer.chrome.com/multidevice/user-agent */ test('detects Chromium-based WebView On Android', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (Linux; Android 5.1.1; Nexus 5 Build/LMY48B; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/43.0.2357.65 Mobile Safari/537.36', )).toEqual({ type: 'browser', @@ -381,7 +381,7 @@ describe('browser detection', () => { }) }) test('detects extended bot info', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.96 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)', )).toEqual({ type: 'bot-device', @@ -393,7 +393,7 @@ describe('browser detection', () => { }) /** Windows CE Ozone (CE 4.2 P/PC 2003) */ test('detects PocketPC2003', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; PPC; 240x320)', )).toEqual({ type: 'browser', @@ -404,7 +404,7 @@ describe('browser detection', () => { }) /** Windows CE Pegasus (CE 1.0x) PIE 1.1 */ test('detects PIE 1.1', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/1.1 (compatible; MSPIE 1.1; Windows CE)', )).toEqual({ type: 'browser', @@ -415,7 +415,7 @@ describe('browser detection', () => { }) /** Windows CE Stinger SmartPhone 2003 */ test('detects NetFront', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'Mozilla/4.0 (PDA; Windows CE;1.0.0) NetFront/3.0', )).toEqual({ type: 'browser', @@ -425,7 +425,7 @@ describe('browser detection', () => { }) }) test('detects extended bot info', () => { - expect.soft(parseUserAgent( + expect(parseUserAgent( 'curl/7.64.1', )).toEqual({ type: 'bot-device', diff --git a/test/node.test.ts b/test/node.test.ts deleted file mode 100644 index bc11463..0000000 --- a/test/node.test.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { detect, getServerVersion } from '../src' - -describe('node', () => { - it('server info is present', () => { - const serverInfo = getServerVersion() - expect(serverInfo).toBeDefined() - expect(serverInfo?.os).toBeDefined() - expect(serverInfo?.name).toBe('node') - expect(serverInfo?.version).toBeDefined() - expect(serverInfo?.nodeMajorVersion).toBeDefined() - expect(serverInfo?.provider).toBeDefined() - expect(serverInfo?.runtime).toBeDefined() - }) - it('detect is server', () => { - const serverInfo = detect() - expect(serverInfo).toBeDefined() - expect(serverInfo?.name).toBe('node') - }) -}) diff --git a/test/server.test.ts b/test/server.test.ts new file mode 100644 index 0000000..51c53b4 --- /dev/null +++ b/test/server.test.ts @@ -0,0 +1,28 @@ +import { runtime } from 'std-env' +import { detect, getNodeVersion, getServerVersion } from '../src' + +describe('Server Detection', () => { + test('Server Detection', () => { + const serverInfo = detect() + expect(serverInfo).toBeDefined() + expect(serverInfo?.type).toBeDefined() + }) + test.skipIf(runtime !== 'node')('Node Detection', () => { + it('node info is present', () => { + const nodeInfo = getNodeVersion() + expect(nodeInfo).toBeDefined() + expect(nodeInfo?.os).toBeDefined() + expect(nodeInfo?.name).toBe('node') + expect(nodeInfo?.version).toBeDefined() + }) + it('server info is present', () => { + const serverInfo = getServerVersion() + expect(serverInfo).toBeDefined() + expect(serverInfo?.os).toBeDefined() + expect(serverInfo?.name).toBe('node') + expect(serverInfo?.version).toBeDefined() + expect(serverInfo?.nodeVersion).toBeDefined() + expect(serverInfo?.nodeMajorVersion).toBeDefined() + }) + }) +}) diff --git a/tsconfig.json b/tsconfig.json index 8e68e8d..e78c663 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,5 +10,5 @@ "strict": true, "skipLibCheck": true }, - "include": ["src", "test"] + "include": ["src", "browser-test", "test"] }