Skip to content

Commit

Permalink
feat: add API to check browser info (#3)
Browse files Browse the repository at this point in the history
Co-authored-by: Bryce Tham <btham@cisco.com>
  • Loading branch information
brycetham and brycetham authored Oct 12, 2023
1 parent 1b5daa0 commit 2e92a27
Show file tree
Hide file tree
Showing 7 changed files with 304 additions and 1 deletion.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ if (WebCapabilities.isCapableOfBackgroundNoiseRemoval() === CapabilityState.CAPA
}
```

Use the `BrowserInfo` class to check certain details about the browser.

```javascript
import { BrowserInfo } from '@webex/web-capabilities';

if (BrowserInfo.isChrome() && BrowserInfo.isSubVersionOf('110')) {
console.log('This browser is Chrome version 110!');
}
```

# Setup

1. Run `yarn` to install dependencies.
Expand Down
4 changes: 3 additions & 1 deletion cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"automock",
"bitauth",
"bitjson",
"Bowser",
"cimg",
"circleci",
"clientjoin",
Expand All @@ -28,6 +29,7 @@
"globby",
"gohri",
"inferencing",
"KHTML",
"libauth",
"mindmeld",
"mkdir",
Expand All @@ -38,8 +40,8 @@
"prettierignore",
"rohit",
"sandboxed",
"tfjs",
"SSDK",
"tfjs",
"trackingid",
"transcoding",
"transpiled",
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,5 +87,8 @@
"ts-jest": "^27.1.2",
"typedoc": "^0.22.10",
"typescript": "^4.5.4"
},
"dependencies": {
"bowser": "^2.11.0"
}
}
132 changes: 132 additions & 0 deletions src/browser-info.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import Bowser from 'bowser';
import { BrowserInfo, BrowserName } from './browser-info';

/**
* Given a browser name, mock a specific user agent.
*
* @param browserName - The name of the browser to mock.
*/
const mockUserAgent = (browserName: BrowserName): void => {
let userAgent;
switch (browserName) {
case BrowserName.CHROME:
userAgent =
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36';
break;
case BrowserName.FIREFOX:
userAgent =
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/118.0';
break;
case BrowserName.EDGE:
userAgent =
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.60';
break;
case BrowserName.SAFARI:
userAgent =
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15';
break;
default:
throw new Error(`Unknown browser name ${browserName}`);
}
// eslint-disable-next-line dot-notation
BrowserInfo['browser'] = Bowser.getParser(userAgent);
};

describe('BrowserInfo', () => {
describe('getting details', () => {
it('should get browser details correctly', () => {
expect.hasAssertions();
mockUserAgent(BrowserName.CHROME);

expect(BrowserInfo.getBrowserDetails().name).toBe(BrowserName.CHROME);
expect(BrowserInfo.getBrowserDetails().version).toBe('118.0.0.0');
});

it('should get OS details correctly', () => {
expect.hasAssertions();
mockUserAgent(BrowserName.CHROME);

expect(BrowserInfo.getOSDetails().name).toBe('Windows');
expect(BrowserInfo.getOSDetails().version).toBe('NT 10.0');
expect(BrowserInfo.getOSDetails().versionName).toBe('10');
});

it('should get platform details correctly', () => {
expect.hasAssertions();
mockUserAgent(BrowserName.CHROME);

expect(BrowserInfo.getPlatformDetails().type).toBe('desktop');
});

it('should get engine details correctly', () => {
expect.hasAssertions();
mockUserAgent(BrowserName.CHROME);

expect(BrowserInfo.getEngineDetails().name).toBe('Blink');
});
});

describe('identifying browsers', () => {
it('should identify a Chrome browser', () => {
expect.hasAssertions();
mockUserAgent(BrowserName.CHROME);

expect(BrowserInfo.isChrome()).toBeTruthy();
expect(BrowserInfo.isFirefox()).toBeFalsy();
expect(BrowserInfo.isEdge()).toBeFalsy();
expect(BrowserInfo.isSafari()).toBeFalsy();
});

it('should identify a Firefox browser', () => {
expect.hasAssertions();
mockUserAgent(BrowserName.FIREFOX);

expect(BrowserInfo.isChrome()).toBeFalsy();
expect(BrowserInfo.isFirefox()).toBeTruthy();
expect(BrowserInfo.isEdge()).toBeFalsy();
expect(BrowserInfo.isSafari()).toBeFalsy();
});

it('should identify a Edge browser', () => {
expect.hasAssertions();
mockUserAgent(BrowserName.EDGE);

expect(BrowserInfo.isChrome()).toBeFalsy();
expect(BrowserInfo.isFirefox()).toBeFalsy();
expect(BrowserInfo.isEdge()).toBeTruthy();
expect(BrowserInfo.isSafari()).toBeFalsy();
});

it('should identify a Safari browser', () => {
expect.hasAssertions();
mockUserAgent(BrowserName.SAFARI);

expect(BrowserInfo.isChrome()).toBeFalsy();
expect(BrowserInfo.isFirefox()).toBeFalsy();
expect(BrowserInfo.isEdge()).toBeFalsy();
expect(BrowserInfo.isSafari()).toBeTruthy();
});
});

describe('comparing versions', () => {
it('should compare browser versions correctly', () => {
expect.hasAssertions();
mockUserAgent(BrowserName.CHROME);

expect(BrowserInfo.isVersionGreaterThan('117')).toBeTruthy();
expect(BrowserInfo.isVersionGreaterThanOrEqualTo('117')).toBeTruthy();
expect(BrowserInfo.isVersionGreaterThanOrEqualTo('118')).toBeTruthy();

expect(BrowserInfo.isVersionLessThan('119')).toBeTruthy();
expect(BrowserInfo.isVersionLessThanOrEqualTo('119')).toBeTruthy();
expect(BrowserInfo.isVersionLessThanOrEqualTo('118')).toBeTruthy();
});

it('should get browser sub-version correctly', () => {
expect.hasAssertions();
mockUserAgent(BrowserName.CHROME);

expect(BrowserInfo.isSubVersionOf('118')).toBeTruthy();
});
});
});
150 changes: 150 additions & 0 deletions src/browser-info.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import Bowser from 'bowser';

/**
* Used by the {@link BrowserInfo} class to check the name of the browser.
*/
export enum BrowserName {
CHROME = 'Chrome',
FIREFOX = 'Firefox',
EDGE = 'Microsoft Edge',
SAFARI = 'Safari',
}

/**
* A class that retrieves and checks certain information about the browser.
*/
export class BrowserInfo {
private static browser = Bowser.getParser(window.navigator.userAgent);

/**
* Get details about the browser, including name and version.
*
* @returns Browser details.
*/
static getBrowserDetails(): Bowser.Parser.BrowserDetails {
return this.browser.getBrowser();
}

/**
* Get details about the OS, including name, version, and version name.
*
* @returns OS details.
*/
static getOSDetails(): Bowser.Parser.OSDetails {
return this.browser.getOS();
}

/**
* Get details about the platform, including type, vendor, and model.
*
* @returns Platform details.
*/
static getPlatformDetails(): Bowser.Parser.PlatformDetails {
return this.browser.getPlatform();
}

/**
* Get details about the engine, including name and version.
*
* @returns Engine details.
*/
static getEngineDetails(): Bowser.Parser.EngineDetails {
return this.browser.getEngine();
}

/**
* Check if current browser is Chrome.
*
* @returns True if Chrome, false otherwise.
*/
static isChrome(): boolean {
return this.browser.getBrowserName() === BrowserName.CHROME;
}

/**
* Check if current browser is Firefox.
*
* @returns True if Firefox, false otherwise.
*/
static isFirefox(): boolean {
return this.browser.getBrowserName() === BrowserName.FIREFOX;
}

/**
* Check if current browser is Edge.
*
* @returns True if Edge, false otherwise.
*/
static isEdge(): boolean {
return this.browser.getBrowserName() === BrowserName.EDGE;
}

/**
* Check if current browser is Safari.
*
* @returns True if Safari, false otherwise.
*/
static isSafari(): boolean {
return this.browser.getBrowserName() === BrowserName.SAFARI;
}

/**
* Check if current browser version is greater than the given version.
*
* @param version - The version to compare with the current browser version.
* @returns True if greater than, false otherwise.
*/
static isVersionGreaterThan(version: string): boolean {
const browserName = this.browser.getBrowserName();
const checkTree = { [browserName]: `>${version}` };
return this.browser.satisfies(checkTree) as boolean;
}

/**
* Check if current browser version is greater than or equal to the given version.
*
* @param version - The version to compare with the current browser version.
* @returns True if greater than or equal to, false otherwise.
*/
static isVersionGreaterThanOrEqualTo(version: string): boolean {
const browserName = this.browser.getBrowserName();
const checkTree = { [browserName]: `>=${version}` };
return this.browser.satisfies(checkTree) as boolean;
}

/**
* Check if current browser version is less than the given version.
*
* @param version - The version to compare with the current browser version.
* @returns True if less than, false otherwise.
*/
static isVersionLessThan(version: string): boolean {
const browserName = this.browser.getBrowserName();
const checkTree = { [browserName]: `<${version}` };
return this.browser.satisfies(checkTree) as boolean;
}

/**
* Check if current browser version is less than or equal to the given version.
*
* @param version - The version to compare with the current browser version.
* @returns True if less than or equal to, false otherwise.
*/
static isVersionLessThanOrEqualTo(version: string): boolean {
const browserName = this.browser.getBrowserName();
const checkTree = { [browserName]: `<=${version}` };
return this.browser.satisfies(checkTree) as boolean;
}

/**
* Check if current browser version is a sub-version of the given version.
*
* @param version - The version to compare with the current browser version.
* @returns True if is sub-version of, false otherwise.
*/
static isSubVersionOf(version: string): boolean {
const browserName = this.browser.getBrowserName();
const checkTree = { [browserName]: `~${version}` };
return this.browser.satisfies(checkTree) as boolean;
}
}
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './browser-info';
export * from './web-capabilities';
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2119,6 +2119,11 @@ bottleneck@^2.18.1:
resolved "https://registry.yarnpkg.com/bottleneck/-/bottleneck-2.19.5.tgz#5df0b90f59fd47656ebe63c78a98419205cadd91"
integrity sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==

bowser@^2.11.0:
version "2.11.0"
resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.11.0.tgz#5ca3c35757a7aa5771500c70a73a9f91ef420a8f"
integrity sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==

brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
Expand Down

0 comments on commit 2e92a27

Please sign in to comment.