From 85a8b6d3ba1ba4acbc6ee36c034463b526c921d0 Mon Sep 17 00:00:00 2001 From: Patryk Ziemkowski Date: Mon, 25 Sep 2023 12:48:35 +0200 Subject: [PATCH] feat: Remove unsupported browser detection as it is not necessary for feat: Remove unsupported browser detection (#401) * feat: Remove unsupported browser detection as it is not necessary for evergreen browsers * update pnpm lock --- packages/webapp/package.json | 4 - packages/webapp/src/app/initApp.tsx | 9 - .../app/unsupported/__tests__/support.spec.ts | 70 ------- .../unsupportedBrowserDetection.spec.ts | 84 -------- .../webapp/src/app/unsupported/support.ts | 26 --- .../unsupportedBrowserDetection.ts | 186 ------------------ pnpm-lock.yaml | 24 --- 7 files changed, 403 deletions(-) delete mode 100644 packages/webapp/src/app/unsupported/__tests__/support.spec.ts delete mode 100644 packages/webapp/src/app/unsupported/__tests__/unsupportedBrowserDetection.spec.ts delete mode 100644 packages/webapp/src/app/unsupported/support.ts delete mode 100644 packages/webapp/src/app/unsupported/unsupportedBrowserDetection.ts diff --git a/packages/webapp/package.json b/packages/webapp/package.json index b4e53bfc0..7d53ce5eb 100644 --- a/packages/webapp/package.json +++ b/packages/webapp/package.json @@ -22,8 +22,6 @@ "intl": "^1.2.5", "lucide-react": "^0.279.0", "qrcode": "^1.5.3", - "semver-compare": "^1.0.0", - "ua-parser-js": "^1.0.36", "react": "^18.2.0", "react-dom": "^18.2.0" }, @@ -54,8 +52,6 @@ "@storybook/client-logger": "^7.4.3", "@storybook/react-vite": "^7.4.3", "@types/qrcode": "^1.5.2", - "@types/semver-compare": "^1.0.1", - "@types/ua-parser-js": "^0.7.37", "@vitejs/plugin-legacy": "^4.1.1", "autoprefixer": "^10.4.16", "concurrently": "^7.6.0", diff --git a/packages/webapp/src/app/initApp.tsx b/packages/webapp/src/app/initApp.tsx index 3b32387cd..71942933a 100644 --- a/packages/webapp/src/app/initApp.tsx +++ b/packages/webapp/src/app/initApp.tsx @@ -7,8 +7,6 @@ import { HelmetProvider } from 'react-helmet-async'; import 'regenerator-runtime/runtime'; import { ApiProvider, RouterProvider, SentryProvider } from './providers'; -import { setUnsupportedClasses } from './unsupported/support'; -import { UnsupportedBrowserDetection } from './unsupported/unsupportedBrowserDetection'; const render = () => { const App = lazy(() => import('./app.component')); @@ -40,13 +38,6 @@ const render = () => { }; export const initApp = async () => { - const detection = new UnsupportedBrowserDetection(); - - if (!detection.isSupported()) { - setUnsupportedClasses(detection.isInAppBrowser, detection.deviceType, detection.isSupported); - return; - } - // Chunked polyfill for browsers without Intl support if (!window.Intl) { Promise.resolve(require('intl')) diff --git a/packages/webapp/src/app/unsupported/__tests__/support.spec.ts b/packages/webapp/src/app/unsupported/__tests__/support.spec.ts deleted file mode 100644 index adbd75254..000000000 --- a/packages/webapp/src/app/unsupported/__tests__/support.spec.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { setUnsupportedClasses } from '../support'; - -describe('setUnsupportedClasses', () => { - const originalClassName = document.documentElement.className; - - afterEach(() => { - document.documentElement.className = originalClassName; - document.title = ''; - }); - - it('should add device type class to document element', () => { - setUnsupportedClasses(false, 'mobile', () => false); - - expect(document.documentElement.className).toContain(`device-mobile`); - }); - - it('should add in-app-browser class to document element when in-app browser detected', () => { - setUnsupportedClasses(true, 'mobile', () => false); - - expect(document.documentElement.className).toContain('in-app-browser'); - }); - - it('should add unsupported class to document element when browser is not supported', () => { - setUnsupportedClasses(false, 'mobile', () => false); - - expect(document.documentElement.className).toContain('unsupported'); - }); - - it('should set unsupported page when browser is not supported', () => { - document.body.innerHTML = ` -
- - `; - - setUnsupportedClasses(false, 'mobile', () => false); - - const unsupportedPageElement = document.querySelector('.unsupported-page') as HTMLElement | null; - const appElement = document.querySelector('#app') as HTMLElement | null; - const headline = unsupportedPageElement?.querySelector('h1'); - - expect(unsupportedPageElement?.style.display).toBe('block'); - expect(appElement?.style.display).toBe('none'); - - expect(headline?.innerText).toBe('Unsupported Browser'); - expect(document.title).toBe('Unsupported Browser'); - }); - - it('should not set unsupported page when browser is supported', async () => { - document.body.innerHTML = ` -
- - `; - - setUnsupportedClasses(true, 'desktop', () => true); - - const unsupportedPageElement = document.querySelector('.unsupported-page') as HTMLElement | null; - const appElement = document.querySelector('#app') as HTMLElement | null; - const headline = unsupportedPageElement?.querySelector('h1') as HTMLElement | null; - - expect(unsupportedPageElement?.style.display).toBe('none'); - expect(appElement).toBeInTheDocument(); - - expect(headline?.innerText).toBe(undefined); - expect(document.title).toBe(''); - }); -}); diff --git a/packages/webapp/src/app/unsupported/__tests__/unsupportedBrowserDetection.spec.ts b/packages/webapp/src/app/unsupported/__tests__/unsupportedBrowserDetection.spec.ts deleted file mode 100644 index 9bccdbc3f..000000000 --- a/packages/webapp/src/app/unsupported/__tests__/unsupportedBrowserDetection.spec.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { UnsupportedBrowserDetection } from '../unsupportedBrowserDetection'; - -/* eslint-disable max-len*/ -const CHROME_UA = - 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'; -const IE_UA = 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)'; -const SAFARI_UA = - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.2 Safari/605.1.15'; -const OPERA_UA = - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36 OPR/74.0.3911.107'; -const CRAWLER_UA = 'Googlebot/2.1'; -const FB_UA = - 'Mozilla/5.0 (Linux; Android 4.4.4; One Build/KTU84L.H4) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/33.0.0.0 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/28.0.0.20.16;]'; -const HEADLESS_CHROME_UA = - 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/79.0.3945.79 Safari/537.36'; -/* eslint-enable max-len*/ - -function setUserAgent(userAgent: string) { - // @ts-ignore - navigator.__defineGetter__('userAgent', () => userAgent); -} - -describe('Utils: UnsupportedBrowserDetection Class', () => { - const checkSupport = ({ isInAppBrowserSupported }: { isInAppBrowserSupported?: boolean }) => - new UnsupportedBrowserDetection(undefined, isInAppBrowserSupported); - - beforeEach(() => { - document.documentElement.className = ''; - }); - - describe('isSupported()', () => { - it('should return true for Chrome', () => { - setUserAgent(CHROME_UA); - const detector = checkSupport({}); - expect(detector.isSupported()).toBe(true); - }); - - it('should return true for Headless Chrome', () => { - setUserAgent(HEADLESS_CHROME_UA); - const detector = checkSupport({}); - expect(detector.isSupported()).toBe(true); - }); - - it('should return true for Opera', () => { - setUserAgent(OPERA_UA); - const detector = checkSupport({}); - expect(detector.isSupported()).toBe(true); - }); - - it('should return true for Safari', () => { - setUserAgent(SAFARI_UA); - const detector = checkSupport({}); - expect(detector.isSupported()).toBe(true); - }); - - it('should return false for IE', () => { - setUserAgent(IE_UA); - const detector = checkSupport({}); - expect(detector.isSupported()).toBe(false); - }); - - it('should return true when is in-app browser and isInAppBrowserSupported equals true', () => { - setUserAgent(FB_UA); - - const detector = checkSupport({ isInAppBrowserSupported: true }); - - expect(detector.isSupported()).toBe(true); - }); - - it('should return false when is in-app browser and isInAppBrowserSupported equals false', () => { - setUserAgent(FB_UA); - - const detector = checkSupport({ isInAppBrowserSupported: false }); - - expect(detector.isSupported()).toBe(false); - }); - - it('should return true for crawler bots', () => { - setUserAgent(CRAWLER_UA); - const detector = checkSupport({}); - expect(detector.isSupported()).toBe(true); - }); - }); -}); diff --git a/packages/webapp/src/app/unsupported/support.ts b/packages/webapp/src/app/unsupported/support.ts deleted file mode 100644 index 749cd37aa..000000000 --- a/packages/webapp/src/app/unsupported/support.ts +++ /dev/null @@ -1,26 +0,0 @@ -export const setUnsupportedClasses = ( - isInAppBrowser: boolean, - deviceType: 'mobile' | 'tablet' | 'desktop', - isSupported: () => boolean -) => { - document.documentElement.className += ` device-${deviceType}`; - - if (isInAppBrowser) { - document.documentElement.className += ' in-app-browser'; - } - - if (!isSupported()) { - document.documentElement.className += ' unsupported'; - const unsupportedPageElement = document.querySelector('.unsupported-page'); - const headline = unsupportedPageElement?.querySelector('h1'); - const appElement = document.querySelector('#app'); - - if (unsupportedPageElement && headline && appElement) { - unsupportedPageElement.style.display = 'block'; - appElement.style.display = 'none'; - - headline.innerText = 'Unsupported Browser'; - document.title = 'Unsupported Browser'; - } - } -}; diff --git a/packages/webapp/src/app/unsupported/unsupportedBrowserDetection.ts b/packages/webapp/src/app/unsupported/unsupportedBrowserDetection.ts deleted file mode 100644 index 366ab8e5c..000000000 --- a/packages/webapp/src/app/unsupported/unsupportedBrowserDetection.ts +++ /dev/null @@ -1,186 +0,0 @@ -import { pickBy } from 'ramda'; -import semverCompare from 'semver-compare'; -import { UAParser } from 'ua-parser-js'; - -type Platform = 'desktop' | 'tablet' | 'mobile'; - -type BrowserVersion = number | string; - -type RequirementType = 'browser' | 'minversion' | 'versions' | 'os' | 'minos'; - -interface BrowserRequirement { - browser: string; - minversion?: BrowserVersion; - versions?: BrowserVersion[]; - os?: string; - minos?: string; -} - -type BrowserCheckResults = Record; - -export type BrowserConfig = Record; - -const DEFAULT_SUPPORTED_BROWSERS_CONFIG: BrowserConfig = { - desktop: [ - { - browser: 'firefox', - minversion: 41, - }, - { - browser: 'ie', - versions: [11, 'edge'], - }, - { - browser: 'chrome', - minversion: 45, - }, - { - browser: 'chrome headless', - }, - { - browser: 'edge', - }, - { - os: 'mac os', - minos: '10.10.0', - browser: 'safari', - minversion: 8, - }, - { - browser: 'opera', - }, - ], - tablet: [ - { - os: 'ios', - minos: '9', - browser: 'mobile safari', - }, - { - os: 'android', - minos: '5.0', - browser: 'chrome', - }, - { - browser: 'chrome headless', - }, - { - browser: 'ie', - versions: [11, 'edge'], - }, - { - browser: 'edge', - }, - { - browser: 'opera', - }, - ], - mobile: [ - { - os: 'ios', - minos: '9', - browser: 'mobile safari', - }, - { - os: 'ios', - minos: '5.0', - browser: 'chrome', - }, - { - browser: 'chrome headless', - }, - { - os: 'android', - minos: '5.0', - browser: 'chrome', - minversion: 50, - }, - { - browser: 'opera', - }, - ], -}; - -export class UnsupportedBrowserDetection { - parser = new UAParser(); - private supportedBrowsersConfig: BrowserConfig; - private readonly isInAppBrowserSupported: boolean; - - constructor(config = DEFAULT_SUPPORTED_BROWSERS_CONFIG, isInAppBrowserSupported = true) { - this.supportedBrowsersConfig = config; - this.isInAppBrowserSupported = isInAppBrowserSupported; - } - - get isInAppBrowser() { - return this.ua.indexOf('FBAN') > -1 || this.ua.indexOf('FBAV') > -1 || this.ua.indexOf('Twitter') > -1; - } - - get isCrawler() { - return ['Googlebot', 'Bingbot', 'Slurp', 'DuckDuckBot', 'Baiduspider', 'YandexBot'].some( - (crawlerName) => this.ua.indexOf(crawlerName) > -1 - ); - } - - get device() { - return this.parser.getDevice(); - } - - get ua() { - return this.parser.getUA(); - } - - get browser() { - return this.parser.getBrowser(); - } - - get os() { - return this.parser.getOS(); - } - - get deviceType(): Platform { - const { type = 'desktop' } = this.device; - return type as Platform; - } - - compareVersions(a: BrowserVersion | undefined, b: string | undefined) { - if (!a || !b) { - return false; - } - - if (typeof a === 'string' || (a as any) instanceof String) { - return semverCompare(a as string, b) <= 0; - } - - return a <= parseInt(b, 10); - } - - isSupported() { - if (this.isCrawler) { - return true; - } - - if (this.isInAppBrowser) { - return this.isInAppBrowserSupported; - } - - const { version: browserVersion = '' } = this.browser; - - return this.supportedBrowsersConfig[this.deviceType].some((options: BrowserRequirement) => { - const { os, minos, browser, minversion, versions } = options; - const parsedVersion = isNaN(parseInt(browserVersion, 10)) - ? browserVersion.toLocaleLowerCase() - : parseInt(browserVersion, 10); - - const checked: BrowserCheckResults = { - os: os === this.os.name?.toLowerCase(), - minos: this.compareVersions(minos, this.os.version), - browser: browser === this.browser.name?.toLowerCase(), - minversion: this.compareVersions(minversion, browserVersion), - versions: versions ? versions.indexOf(parsedVersion) >= 0 : false, - }; - - const requiredChecks: BrowserCheckResults = pickBy((val, key) => Object.keys(options).includes(key), checked); - return !Object.values(requiredChecks).includes(false); - }); - } -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a3b8fad82..02280bd16 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -607,12 +607,6 @@ importers: react-dom: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) - semver-compare: - specifier: ^1.0.0 - version: 1.0.0 - ua-parser-js: - specifier: ^1.0.36 - version: 1.0.36 devDependencies: '@esbuild-plugins/node-globals-polyfill': specifier: ^0.2.3 @@ -692,12 +686,6 @@ importers: '@types/qrcode': specifier: ^1.5.2 version: 1.5.2 - '@types/semver-compare': - specifier: ^1.0.1 - version: 1.0.1 - '@types/ua-parser-js': - specifier: ^0.7.37 - version: 0.7.37 '@vitejs/plugin-legacy': specifier: ^4.1.1 version: 4.1.1(terser@5.20.0)(vite@4.4.9) @@ -12225,10 +12213,6 @@ packages: /@types/scheduler@0.16.3: resolution: {integrity: sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==} - /@types/semver-compare@1.0.1: - resolution: {integrity: sha512-wx2LQVvKlEkhXp/HoKIZ/aSL+TvfJdKco8i0xJS3aR877mg4qBHzNT6+B5a61vewZHo79EdZavskGnRXEC2H6A==} - dev: true - /@types/semver@7.5.2: resolution: {integrity: sha512-7aqorHYgdNO4DM36stTiGO3DvKoex9TQRwsJU6vMaFGyqpBA1MNZkz+PG3gaNUPpTAOYhT1WR7M1JyA3fbS9Cw==} dev: true @@ -12283,10 +12267,6 @@ packages: resolution: {integrity: sha512-THo502dA5PzG/sfQH+42Lw3fvmYkceefOspdCwpHRul8ik2Jv1K8I5OZz1AT3/rs46kwgMCe9bSBmDLYkkOMGg==} dev: true - /@types/ua-parser-js@0.7.37: - resolution: {integrity: sha512-4sOxS3ZWXC0uHJLYcWAaLMxTvjRX3hT96eF4YWUh1ovTaenvibaZOE5uXtIp4mksKMLRwo7YDiCBCw6vBiUPVg==} - dev: true - /@types/unist@2.0.8: resolution: {integrity: sha512-d0XxK3YTObnWVp6rZuev3c49+j4Lo8g4L1ZRm9z5L0xpoZycUPshHgczK5gsUMaZOstjVYYi09p5gYvUtfChYw==} @@ -28446,10 +28426,6 @@ packages: dependencies: node-forge: 1.3.1 - /semver-compare@1.0.0: - resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==} - dev: false - /semver-diff@3.1.1: resolution: {integrity: sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==} engines: {node: '>=8'}