mirror of
https://github.com/cypress-io/cypress.git
synced 2026-02-23 07:39:52 -06:00
chore: adding granular Firefox browser validation (#23164)
* chore: render FF 101 and 102 as unsupported on Windows * Updating specs * Little refactor * Adding a few more specs * Moving browsers to launcher * Adding a few more specs * Removing exports that no longer exist * Few more tests * Apply suggestions from code review for more specific warning message Co-authored-by: Zach Bloomquist <git@chary.us> * Update packages/launcher/lib/detect.ts Co-authored-by: Ryan Manuel <ryanm@cypress.io> Co-authored-by: Zach Bloomquist <git@chary.us> Co-authored-by: Ryan Manuel <ryanm@cypress.io>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import '@testing-library/cypress/add-commands'
|
||||
import { browsers } from '@packages/types/src/browser'
|
||||
import { browsers } from '@packages/launcher/lib/browsers'
|
||||
import { installCustomPercyCommand } from '@packages/ui-components/cypress/support/customPercyCommand'
|
||||
import { configure } from '@testing-library/cypress'
|
||||
import i18n from '../../../src/locales/en-US.json'
|
||||
|
||||
@@ -1,14 +1,161 @@
|
||||
import Debug from 'debug'
|
||||
import * as cp from 'child_process'
|
||||
import { browsers, FoundBrowser } from '@packages/types'
|
||||
import type { Browser, BrowserValidatorResult, FoundBrowser } from '@packages/types'
|
||||
import type { Readable } from 'stream'
|
||||
|
||||
export const debug = Debug('cypress:launcher:browsers')
|
||||
|
||||
export { browsers }
|
||||
// Chrome started exposing CDP 1.3 in 64
|
||||
export const MIN_CHROME_VERSION = 64
|
||||
|
||||
// Firefox started exposing CDP in 86
|
||||
export const MIN_FIREFOX_VERSION = 86
|
||||
|
||||
// Edge switched to Blink in 79
|
||||
export const MIN_EDGE_VERSION = 79
|
||||
|
||||
// Compares a detected browser's major version to its minimum supported version
|
||||
// to determine if the browser is supported by Cypress.
|
||||
export const validateMinVersion = (browser: FoundBrowser): BrowserValidatorResult => {
|
||||
const minSupportedVersion = browser.minSupportedVersion
|
||||
const majorVersion = browser.majorVersion
|
||||
|
||||
if (majorVersion && minSupportedVersion && parseInt(majorVersion) < minSupportedVersion) {
|
||||
return {
|
||||
isSupported: false,
|
||||
warningMessage: `Cypress does not support running ${browser.displayName} version ${majorVersion}. To use ${browser.displayName} with Cypress, install a version of ${browser.displayName} newer than or equal to ${minSupportedVersion}.`,
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
isSupported: true,
|
||||
}
|
||||
}
|
||||
|
||||
/** list of the browsers we can detect and use by default */
|
||||
|
||||
export const browsers: Browser[] = [
|
||||
{
|
||||
name: 'chrome',
|
||||
family: 'chromium',
|
||||
channel: 'stable',
|
||||
displayName: 'Chrome',
|
||||
versionRegex: /Google Chrome (\S+)/m,
|
||||
binary: ['google-chrome', 'chrome', 'google-chrome-stable'],
|
||||
minSupportedVersion: MIN_CHROME_VERSION,
|
||||
},
|
||||
{
|
||||
name: 'chromium',
|
||||
family: 'chromium',
|
||||
// technically Chromium is always in development
|
||||
channel: 'stable',
|
||||
displayName: 'Chromium',
|
||||
versionRegex: /Chromium (\S+)/m,
|
||||
binary: ['chromium-browser', 'chromium'],
|
||||
minSupportedVersion: MIN_CHROME_VERSION,
|
||||
},
|
||||
{
|
||||
name: 'chrome',
|
||||
family: 'chromium',
|
||||
channel: 'beta',
|
||||
displayName: 'Chrome Beta',
|
||||
versionRegex: /Google Chrome (\S+) beta/m,
|
||||
binary: 'google-chrome-beta',
|
||||
minSupportedVersion: MIN_CHROME_VERSION,
|
||||
},
|
||||
{
|
||||
name: 'chrome',
|
||||
family: 'chromium',
|
||||
channel: 'canary',
|
||||
displayName: 'Canary',
|
||||
versionRegex: /Google Chrome Canary (\S+)/m,
|
||||
binary: 'google-chrome-canary',
|
||||
minSupportedVersion: MIN_CHROME_VERSION,
|
||||
},
|
||||
{
|
||||
name: 'firefox',
|
||||
family: 'firefox',
|
||||
channel: 'stable',
|
||||
displayName: 'Firefox',
|
||||
// Mozilla Firefox 70.0.1
|
||||
versionRegex: /^Mozilla Firefox ([^\sab]+)$/m,
|
||||
binary: 'firefox',
|
||||
minSupportedVersion: MIN_FIREFOX_VERSION,
|
||||
validator: (browser: FoundBrowser, platform: NodeJS.Platform): BrowserValidatorResult => {
|
||||
// Firefox 101 and 102 on Windows features a bug that results in Cypress being unable
|
||||
// to connect to the launched browser. A fix was first released in stable 103.
|
||||
// See https://github.com/cypress-io/cypress/issues/22086 for related info.
|
||||
|
||||
if (platform === 'win32' && browser.majorVersion && ['101', '102'].includes(browser.majorVersion)) {
|
||||
return {
|
||||
isSupported: false,
|
||||
warningMessage: `Cypress does not support running ${browser.displayName} version ${browser.majorVersion} on Windows due to a blocking bug in ${browser.displayName}. To use ${browser.displayName} with Cypress on Windows, install version 103 or newer.`,
|
||||
}
|
||||
}
|
||||
|
||||
return validateMinVersion(browser)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'firefox',
|
||||
family: 'firefox',
|
||||
channel: 'dev',
|
||||
displayName: 'Firefox Developer Edition',
|
||||
// Mozilla Firefox 73.0b12
|
||||
versionRegex: /^Mozilla Firefox (\S+b\S*)$/m,
|
||||
// ubuntu PPAs install it as firefox
|
||||
binary: ['firefox-developer-edition', 'firefox'],
|
||||
minSupportedVersion: MIN_FIREFOX_VERSION,
|
||||
},
|
||||
{
|
||||
name: 'firefox',
|
||||
family: 'firefox',
|
||||
channel: 'nightly',
|
||||
displayName: 'Firefox Nightly',
|
||||
// Mozilla Firefox 74.0a1
|
||||
versionRegex: /^Mozilla Firefox (\S+a\S*)$/m,
|
||||
// ubuntu PPAs install it as firefox-trunk
|
||||
binary: ['firefox-nightly', 'firefox-trunk'],
|
||||
minSupportedVersion: MIN_FIREFOX_VERSION,
|
||||
},
|
||||
{
|
||||
name: 'edge',
|
||||
family: 'chromium',
|
||||
channel: 'stable',
|
||||
displayName: 'Edge',
|
||||
versionRegex: /Microsoft Edge (\S+)/m,
|
||||
binary: ['edge', 'microsoft-edge'],
|
||||
minSupportedVersion: MIN_EDGE_VERSION,
|
||||
},
|
||||
{
|
||||
name: 'edge',
|
||||
family: 'chromium',
|
||||
channel: 'canary',
|
||||
displayName: 'Edge Canary',
|
||||
versionRegex: /Microsoft Edge Canary (\S+)/m,
|
||||
binary: 'edge-canary',
|
||||
minSupportedVersion: MIN_EDGE_VERSION,
|
||||
},
|
||||
{
|
||||
name: 'edge',
|
||||
family: 'chromium',
|
||||
channel: 'beta',
|
||||
displayName: 'Edge Beta',
|
||||
versionRegex: /Microsoft Edge Beta (\S+)/m,
|
||||
binary: 'edge-beta',
|
||||
minSupportedVersion: MIN_EDGE_VERSION,
|
||||
},
|
||||
{
|
||||
name: 'edge',
|
||||
family: 'chromium',
|
||||
channel: 'dev',
|
||||
displayName: 'Edge Dev',
|
||||
versionRegex: /Microsoft Edge Dev (\S+)/m,
|
||||
binary: ['edge-dev', 'microsoft-edge-dev'],
|
||||
minSupportedVersion: MIN_EDGE_VERSION,
|
||||
},
|
||||
]
|
||||
|
||||
/** starts a found browser and opens URL if given one */
|
||||
|
||||
export type LaunchedBrowser = cp.ChildProcessByStdio<null, Readable, Readable>
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import Bluebird from 'bluebird'
|
||||
import _, { compact, extend, find } from 'lodash'
|
||||
import os from 'os'
|
||||
import { browsers } from './browsers'
|
||||
import { browsers, validateMinVersion } from './browsers'
|
||||
import * as darwinHelper from './darwin'
|
||||
import { notDetectedAtPathErr } from './errors'
|
||||
import * as linuxHelper from './linux'
|
||||
import Debug from 'debug'
|
||||
import type {
|
||||
Browser,
|
||||
BrowserValidator,
|
||||
DetectedBrowser,
|
||||
FoundBrowser,
|
||||
} from '@packages/types'
|
||||
@@ -25,20 +26,24 @@ type HasVersion = Omit<Partial<FoundBrowser>, 'version' | 'name'> & {
|
||||
name: string
|
||||
}
|
||||
|
||||
export const setMajorVersion = <T extends HasVersion>(browser: T): T => {
|
||||
const ver = browser.version.split('.')[0] ?? browser.version
|
||||
const majorVersion = parseInt(ver) || browser.version
|
||||
export const getMajorVersion = (version: string): string => {
|
||||
return version.split('.')[0]
|
||||
}
|
||||
|
||||
const unsupportedVersion = browser.minSupportedVersion && majorVersion < browser.minSupportedVersion
|
||||
// Determines if found browser is supported by Cypress. If found to be
|
||||
// unsupported, the browser will be unavailable for selection and
|
||||
// will present the determined warning message to the user.
|
||||
const validateCypressSupport = (validator: BrowserValidator | undefined, browser: FoundBrowser, platform: NodeJS.Platform) => {
|
||||
// If no validator parameter is provided, we fall back to validating against
|
||||
// the browser's minimum supported version
|
||||
const { isSupported, warningMessage } = (validator || validateMinVersion)(browser, platform)
|
||||
|
||||
const foundBrowser = extend({}, browser, { majorVersion })
|
||||
|
||||
if (unsupportedVersion) {
|
||||
foundBrowser.unsupportedVersion = true
|
||||
foundBrowser.warning = `Cypress does not support running ${browser.displayName} version ${majorVersion}. To use ${browser.displayName} with Cypress, install a version of ${browser.displayName} newer than or equal to ${browser.minSupportedVersion}.`
|
||||
if (isSupported) {
|
||||
return
|
||||
}
|
||||
|
||||
return foundBrowser
|
||||
browser.unsupportedVersion = true
|
||||
browser.warning = warningMessage
|
||||
}
|
||||
|
||||
type PlatformHelper = {
|
||||
@@ -126,8 +131,14 @@ function checkOneBrowser (browser: Browser): Promise<boolean | HasVersion> {
|
||||
|
||||
return lookup(platform, browser)
|
||||
.then((val) => ({ ...browser, ...val }))
|
||||
.then((val) => _.pick(val, pickBrowserProps) as HasVersion)
|
||||
.then((browser) => setMajorVersion(browser))
|
||||
.then((val) => _.pick(val, pickBrowserProps) as FoundBrowser)
|
||||
.then((foundBrowser) => {
|
||||
foundBrowser.majorVersion = getMajorVersion(foundBrowser.version)
|
||||
|
||||
validateCypressSupport(browser.validator, foundBrowser, platform)
|
||||
|
||||
return foundBrowser
|
||||
})
|
||||
.catch(failed)
|
||||
}
|
||||
|
||||
@@ -185,16 +196,19 @@ export const detectByPath = (
|
||||
const setCustomBrowserData = (browser: Browser, path: string, versionStr: string): FoundBrowser => {
|
||||
const version = helper.getVersionNumber(versionStr, browser)
|
||||
|
||||
let parsedBrowser = extend({}, browser, {
|
||||
const parsedBrowser = extend({}, browser, {
|
||||
name: browser.name,
|
||||
displayName: `Custom ${browser.displayName}`,
|
||||
info: `Loaded from ${path}`,
|
||||
custom: true,
|
||||
path,
|
||||
version,
|
||||
})
|
||||
majorVersion: getMajorVersion(version),
|
||||
}) as FoundBrowser
|
||||
|
||||
return setMajorVersion(parsedBrowser)
|
||||
validateCypressSupport(browser.validator, parsedBrowser, os.platform())
|
||||
|
||||
return parsedBrowser
|
||||
}
|
||||
|
||||
const pathData = helper.getPathData(path)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import _ from 'lodash'
|
||||
import { browsers } from '../../lib/browsers'
|
||||
import { browsers, validateMinVersion } from '../../lib/browsers'
|
||||
import { expect } from 'chai'
|
||||
import { FoundBrowser } from '@packages/types'
|
||||
const snapshot = require('snap-shot-it')
|
||||
|
||||
describe('browsers', () => {
|
||||
@@ -14,4 +15,179 @@ describe('browsers', () => {
|
||||
return versionRegex.multiline
|
||||
}))).to.be.true
|
||||
})
|
||||
|
||||
describe('firefox-stable validator', () => {
|
||||
const firefoxBrowser = {
|
||||
...browsers.find(({ name, channel }) => name === 'firefox' && channel === 'stable'),
|
||||
path: '/path/to/firefox',
|
||||
}
|
||||
|
||||
context('Windows', () => {
|
||||
it('validates against version 101', () => {
|
||||
const foundBrowser = {
|
||||
...firefoxBrowser,
|
||||
version: '101.1.0',
|
||||
majorVersion: '101',
|
||||
} as FoundBrowser
|
||||
|
||||
const result = firefoxBrowser.validator(foundBrowser, 'win32')
|
||||
|
||||
expect(result.isSupported).to.be.false
|
||||
expect(result.warningMessage).to.contain('Cypress does not support running Firefox version 101 on Windows due to a blocking bug in Firefox.')
|
||||
})
|
||||
|
||||
it('validates against version 102', () => {
|
||||
const foundBrowser = {
|
||||
...firefoxBrowser,
|
||||
version: '102.1.0',
|
||||
majorVersion: '102',
|
||||
path: '/path/to/firefox',
|
||||
} as FoundBrowser
|
||||
|
||||
const result = firefoxBrowser.validator(foundBrowser, 'win32')
|
||||
|
||||
expect(result.isSupported).to.be.false
|
||||
expect(result.warningMessage).to.contain('Cypress does not support running Firefox version 102 on Windows due to a blocking bug in Firefox.')
|
||||
})
|
||||
|
||||
it('validates against minimum supported version', () => {
|
||||
const foundBrowser = {
|
||||
...firefoxBrowser,
|
||||
version: '85.1.0',
|
||||
majorVersion: '85',
|
||||
} as FoundBrowser
|
||||
|
||||
const result = firefoxBrowser.validator(foundBrowser, 'win32')
|
||||
|
||||
expect(result.isSupported).to.be.false
|
||||
expect(result.warningMessage).to.contain('Cypress does not support running Firefox version 85.')
|
||||
})
|
||||
|
||||
it('successfully validates a version equal to the minimum', () => {
|
||||
const foundBrowser = {
|
||||
...firefoxBrowser,
|
||||
version: '86.1.0',
|
||||
majorVersion: '86',
|
||||
} as FoundBrowser
|
||||
|
||||
const result = firefoxBrowser.validator(foundBrowser, 'win32')
|
||||
|
||||
expect(result.isSupported).to.be.true
|
||||
expect(result.warningMessage).to.be.undefined
|
||||
})
|
||||
|
||||
it('successfully validates a version greater than the minimum', () => {
|
||||
const foundBrowser = {
|
||||
...firefoxBrowser,
|
||||
version: '103.1.0',
|
||||
majorVersion: '103',
|
||||
} as FoundBrowser
|
||||
|
||||
const result = firefoxBrowser.validator(foundBrowser, 'win32')
|
||||
|
||||
expect(result.isSupported).to.be.true
|
||||
expect(result.warningMessage).to.be.undefined
|
||||
})
|
||||
})
|
||||
|
||||
context('Not Windows', () => {
|
||||
it('validates 101 as supported', () => {
|
||||
const foundBrowser = {
|
||||
...firefoxBrowser,
|
||||
version: '101.1.0',
|
||||
majorVersion: '101',
|
||||
} as FoundBrowser
|
||||
|
||||
const result = firefoxBrowser.validator(foundBrowser, 'darwin')
|
||||
|
||||
expect(result.isSupported).to.be.true
|
||||
expect(result.warningMessage).to.be.undefined
|
||||
})
|
||||
|
||||
it('validates 102 as supported', () => {
|
||||
const foundBrowser = {
|
||||
...firefoxBrowser,
|
||||
version: '102.2.0',
|
||||
majorVersion: '102',
|
||||
} as FoundBrowser
|
||||
|
||||
const result = firefoxBrowser.validator(foundBrowser, 'darwin')
|
||||
|
||||
expect(result.isSupported).to.be.true
|
||||
expect(result.warningMessage).to.be.undefined
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('#validateMinVersion', () => {
|
||||
const testBrowser = {
|
||||
displayName: 'Test Browser',
|
||||
minSupportedVersion: 50,
|
||||
path: '/path/to/browser',
|
||||
}
|
||||
|
||||
it('validates against minimum supported version', () => {
|
||||
const foundBrowser = {
|
||||
...testBrowser,
|
||||
version: '40.1.0',
|
||||
majorVersion: '40',
|
||||
} as FoundBrowser
|
||||
|
||||
const result = validateMinVersion(foundBrowser)
|
||||
|
||||
expect(result.isSupported).to.be.false
|
||||
expect(result.warningMessage).to.contain('Cypress does not support running Test Browser version 40.')
|
||||
})
|
||||
|
||||
it('successfully validates a version equal to the minimum', () => {
|
||||
const foundBrowser = {
|
||||
...testBrowser,
|
||||
version: '50.1.0',
|
||||
majorVersion: '50',
|
||||
} as FoundBrowser
|
||||
|
||||
const result = validateMinVersion(foundBrowser)
|
||||
|
||||
expect(result.isSupported).to.be.true
|
||||
expect(result.warningMessage).to.be.undefined
|
||||
})
|
||||
|
||||
it('successfully validates a version greater than the minimum', () => {
|
||||
const foundBrowser = {
|
||||
...testBrowser,
|
||||
version: '90.1.0',
|
||||
majorVersion: '90',
|
||||
} as FoundBrowser
|
||||
|
||||
const result = validateMinVersion(foundBrowser)
|
||||
|
||||
expect(result.isSupported).to.be.true
|
||||
expect(result.warningMessage).to.be.undefined
|
||||
})
|
||||
|
||||
it('does not validate with missing minSupportedVersion', () => {
|
||||
const foundBrowser = {
|
||||
...testBrowser,
|
||||
version: '90.1.0',
|
||||
} as FoundBrowser
|
||||
|
||||
const result = validateMinVersion(foundBrowser)
|
||||
|
||||
expect(result.isSupported).to.be.true
|
||||
expect(result.warningMessage).to.be.undefined
|
||||
})
|
||||
|
||||
it('does not validate with missing majorVersion', () => {
|
||||
const foundBrowser = {
|
||||
...testBrowser,
|
||||
minSupportedVersion: 90,
|
||||
version: '90.1.0',
|
||||
} as FoundBrowser
|
||||
|
||||
const result = validateMinVersion(foundBrowser)
|
||||
|
||||
expect(result.isSupported).to.be.true
|
||||
expect(result.warningMessage).to.be.undefined
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,18 +1,29 @@
|
||||
require('../spec_helper')
|
||||
import _ from 'lodash'
|
||||
import { detect, detectByPath, setMajorVersion } from '../../lib/detect'
|
||||
import { detect, detectByPath, getMajorVersion } from '../../lib/detect'
|
||||
import * as browsers from '../../lib/browsers'
|
||||
import { goalBrowsers } from '../fixtures'
|
||||
import { expect } from 'chai'
|
||||
import { utils } from '../../lib/utils'
|
||||
import sinon, { SinonStub } from 'sinon'
|
||||
import os from 'os'
|
||||
import { log } from '../log'
|
||||
import * as linuxHelper from '../../lib/linux'
|
||||
import * as darwinHelper from '../../lib/darwin'
|
||||
import * as windowsHelper from '../../lib/windows'
|
||||
import type { Browser } from '@packages/types'
|
||||
|
||||
const isWindows = () => {
|
||||
return os.platform() === 'win32'
|
||||
}
|
||||
|
||||
describe('browser detection', () => {
|
||||
const stubHelpers = (detect) => {
|
||||
sinon.stub(linuxHelper, 'detect').callsFake(detect)
|
||||
sinon.stub(darwinHelper, 'detect').callsFake(detect)
|
||||
sinon.stub(windowsHelper, 'detect').callsFake(detect)
|
||||
}
|
||||
|
||||
describe('detect', () => {
|
||||
// making simple to debug tests
|
||||
// using DEBUG=... flag
|
||||
const checkBrowsers = (browsers) => {
|
||||
@@ -38,48 +49,80 @@ describe('browser detection', () => {
|
||||
return detect().then(checkBrowsers)
|
||||
})
|
||||
|
||||
context('#setMajorVersion', () => {
|
||||
it('major version is converted to number when string of numbers', () => {
|
||||
const foundBrowser = {
|
||||
name: 'test browser',
|
||||
version: '11.22.33',
|
||||
}
|
||||
|
||||
const res = setMajorVersion(foundBrowser)
|
||||
|
||||
// @ts-ignore
|
||||
expect(res.majorVersion).to.equal(11)
|
||||
})
|
||||
|
||||
it('falls back to version when unconventional browser version', () => {
|
||||
const foundBrowser = {
|
||||
name: 'test browser',
|
||||
version: 'VMware Fusion 12.1.0',
|
||||
}
|
||||
|
||||
const res = setMajorVersion(foundBrowser)
|
||||
|
||||
// @ts-ignore
|
||||
expect(res.majorVersion).to.equal(foundBrowser.version)
|
||||
})
|
||||
|
||||
it('creates warning when version is unsupported', () => {
|
||||
const foundBrowser = {
|
||||
displayName: 'TestBro',
|
||||
name: 'test browser',
|
||||
version: '9000.1',
|
||||
minSupportedVersion: 9001,
|
||||
}
|
||||
|
||||
const res = setMajorVersion(foundBrowser)
|
||||
|
||||
// @ts-ignore
|
||||
expect(res.warning).to.contain('does not support running TestBro version 9000')
|
||||
.and.contain('TestBro newer than or equal to 9001')
|
||||
describe('#getMajorVersion', () => {
|
||||
it('parses major version from provided string', () => {
|
||||
expect(getMajorVersion('123.45.67')).to.eq('123')
|
||||
expect(getMajorVersion('Browser 77.1.0')).to.eq('Browser 77')
|
||||
expect(getMajorVersion('999')).to.eq('999')
|
||||
})
|
||||
})
|
||||
|
||||
context('#detectByPath', () => {
|
||||
describe('#detect', () => {
|
||||
const testBrowser = {
|
||||
name: 'test-browser',
|
||||
family: 'chromium',
|
||||
channel: 'test-channel',
|
||||
displayName: 'Test Browser',
|
||||
minSupportedVersion: 1,
|
||||
versionRegex: /Test Browser (\S+)/m,
|
||||
binary: 'test-browser-beta',
|
||||
}
|
||||
|
||||
it('validates browser with own validator property', async () => {
|
||||
stubHelpers((browser) => {
|
||||
return Promise.resolve({
|
||||
name: browser.name,
|
||||
path: '/path/to/test-browser',
|
||||
version: `${browser.minSupportedVersion}`,
|
||||
})
|
||||
})
|
||||
|
||||
const mockValidator = sinon.stub().returns({ isSupported: true })
|
||||
|
||||
const foundBrowsers = await detect([{ ...testBrowser as Browser, validator: mockValidator }])
|
||||
|
||||
expect(foundBrowsers).to.have.length(1)
|
||||
|
||||
const foundTestBrowser = foundBrowsers[0]
|
||||
|
||||
expect(foundTestBrowser.name).to.eq('test-browser')
|
||||
expect(foundTestBrowser.displayName).to.eq('Test Browser')
|
||||
expect(foundTestBrowser.majorVersion, 'majorVersion').to.eq('1')
|
||||
expect(foundTestBrowser.unsupportedVersion, 'unsupportedVersion').to.be.undefined
|
||||
expect(foundTestBrowser.warning, 'warning').to.be.undefined
|
||||
expect(mockValidator).to.have.been.called
|
||||
})
|
||||
|
||||
it('validates browser with default minVersionValidator', async () => {
|
||||
stubHelpers((browser) => {
|
||||
return Promise.resolve({
|
||||
name: browser.name,
|
||||
path: '/path/to/test-browser',
|
||||
version: `${browser.minSupportedVersion}`,
|
||||
})
|
||||
})
|
||||
|
||||
const mockValidator = sinon.stub(browsers, 'validateMinVersion').returns({
|
||||
isSupported: false,
|
||||
warningMessage: 'This is a bad version',
|
||||
})
|
||||
|
||||
const foundBrowsers = await detect([{ ...testBrowser as Browser }])
|
||||
|
||||
expect(foundBrowsers).to.have.length(1)
|
||||
|
||||
const foundTestBrowser = foundBrowsers[0]
|
||||
|
||||
expect(foundTestBrowser.name).to.eq('test-browser')
|
||||
expect(foundTestBrowser.displayName).to.eq('Test Browser')
|
||||
expect(foundTestBrowser.majorVersion, 'majorVersion').to.eq('1')
|
||||
expect(foundTestBrowser.unsupportedVersion, 'unsupportedVersion').to.be.true
|
||||
expect(foundTestBrowser.warning, 'warning').to.eq('This is a bad version')
|
||||
expect(mockValidator).to.have.been.called
|
||||
})
|
||||
})
|
||||
|
||||
describe('#detectByPath', () => {
|
||||
let execa: SinonStub
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -110,7 +153,7 @@ describe('browser detection', () => {
|
||||
info: 'Loaded from /foo/bar/browser',
|
||||
custom: true,
|
||||
version: '9001.1.2.3',
|
||||
majorVersion: 9001,
|
||||
majorVersion: '9001',
|
||||
path: '/foo/bar/browser',
|
||||
}),
|
||||
)
|
||||
@@ -151,7 +194,7 @@ describe('browser detection', () => {
|
||||
info: 'Loaded from /Applications/My Shiny New Browser.app',
|
||||
custom: true,
|
||||
version: '100.1.2.3',
|
||||
majorVersion: 100,
|
||||
majorVersion: '100',
|
||||
path: '/Applications/My Shiny New Browser.app',
|
||||
}),
|
||||
)
|
||||
@@ -164,6 +207,7 @@ describe('browser detection', () => {
|
||||
|
||||
const foundBrowser = await detectByPath('/good-firefox')
|
||||
|
||||
expect(foundBrowser.unsupportedVersion).to.be.true
|
||||
expect(foundBrowser.warning).to.contain('does not support running Custom Firefox version 85')
|
||||
.and.contain('Firefox newer than or equal to 86')
|
||||
})
|
||||
|
||||
@@ -68,7 +68,7 @@ describe('linux browser detection', () => {
|
||||
name: 'chromium',
|
||||
family: 'chromium',
|
||||
displayName: 'Chromium',
|
||||
majorVersion: 64,
|
||||
majorVersion: '64',
|
||||
minSupportedVersion: 64,
|
||||
path: 'chromium',
|
||||
profilePath: '/home/foo/snap/chromium/current',
|
||||
@@ -86,7 +86,7 @@ describe('linux browser detection', () => {
|
||||
name: 'firefox',
|
||||
family: 'firefox',
|
||||
displayName: 'Firefox',
|
||||
majorVersion: 99,
|
||||
majorVersion: '99',
|
||||
minSupportedVersion: 86,
|
||||
path: 'firefox',
|
||||
profilePath: '/home/foo/snap/firefox/current',
|
||||
@@ -169,14 +169,14 @@ describe('linux browser detection', () => {
|
||||
name: 'test-browser-name',
|
||||
version: '100.1.2.3',
|
||||
path: 'test-browser',
|
||||
majorVersion: 100,
|
||||
majorVersion: '100',
|
||||
},
|
||||
{
|
||||
displayName: 'Foo Browser',
|
||||
name: 'foo-browser',
|
||||
version: '100.1.2.3',
|
||||
path: 'foo-browser',
|
||||
majorVersion: 100,
|
||||
majorVersion: '100',
|
||||
},
|
||||
]
|
||||
|
||||
@@ -202,7 +202,7 @@ describe('linux browser detection', () => {
|
||||
name: 'foo-browser',
|
||||
version: '100.1.2.3',
|
||||
path: 'foo-browser',
|
||||
majorVersion: 100,
|
||||
majorVersion: '100',
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ describe('windows browser detection', () => {
|
||||
info: `Loaded from ${win10Path}`,
|
||||
custom: true,
|
||||
version: '100',
|
||||
majorVersion: 100,
|
||||
majorVersion: '100',
|
||||
path: win10Path,
|
||||
}),
|
||||
)
|
||||
@@ -136,7 +136,7 @@ describe('windows browser detection', () => {
|
||||
info: `Loaded from ${win10Path}`,
|
||||
custom: true,
|
||||
version: '100',
|
||||
majorVersion: 100,
|
||||
majorVersion: '100',
|
||||
path: win10Path,
|
||||
}),
|
||||
)
|
||||
|
||||
@@ -6,6 +6,15 @@ export type BrowserChannel = 'stable' | 'canary' | 'beta' | 'dev' | 'nightly' |
|
||||
|
||||
export type BrowserFamily = typeof BROWSER_FAMILY[number]
|
||||
|
||||
export type BrowserValidatorResult = {
|
||||
// whether or not the browser is supported by Cypress
|
||||
isSupported: boolean
|
||||
// optional warning message that will be shown in the GUI
|
||||
warningMessage?: string
|
||||
}
|
||||
|
||||
export type BrowserValidator = (browser: FoundBrowser, platform: NodeJS.Platform) => BrowserValidatorResult
|
||||
|
||||
/**
|
||||
* Represents a typical browser to try to detect and turn into a `FoundBrowser`.
|
||||
*/
|
||||
@@ -38,12 +47,14 @@ export type Browser = {
|
||||
info?: string
|
||||
/** if set, the majorVersion must be >= this to be run in Cypress */
|
||||
minSupportedVersion?: number
|
||||
/** if set, is called to determine if found browser is supported by Cypress */
|
||||
validator?: BrowserValidator
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a real browser that exists on the user's system.
|
||||
*/
|
||||
export type FoundBrowser = Omit<Browser, 'versionRegex' | 'binary'> & {
|
||||
export type FoundBrowser = Omit<Browser, 'versionRegex' | 'binary' | 'validator'> & {
|
||||
path: string
|
||||
version: string
|
||||
majorVersion?: string | null
|
||||
@@ -57,123 +68,6 @@ export type FoundBrowser = Omit<Browser, 'versionRegex' | 'binary'> & {
|
||||
*/
|
||||
export type DetectedBrowser = Pick<FoundBrowser, 'name' | 'path' | 'version'>
|
||||
|
||||
// Chrome started exposing CDP 1.3 in 64
|
||||
export const MIN_CHROME_VERSION = 64
|
||||
|
||||
// Firefox started exposing CDP in 86
|
||||
export const MIN_FIREFOX_VERSION = 86
|
||||
|
||||
// Edge switched to Blink in 79
|
||||
export const MIN_EDGE_VERSION = 79
|
||||
|
||||
export const browsers: Browser[] = [
|
||||
{
|
||||
name: 'chrome',
|
||||
family: 'chromium',
|
||||
channel: 'stable',
|
||||
displayName: 'Chrome',
|
||||
versionRegex: /Google Chrome (\S+)/m,
|
||||
binary: ['google-chrome', 'chrome', 'google-chrome-stable'],
|
||||
minSupportedVersion: MIN_CHROME_VERSION,
|
||||
},
|
||||
{
|
||||
name: 'chromium',
|
||||
family: 'chromium',
|
||||
// technically Chromium is always in development
|
||||
channel: 'stable',
|
||||
displayName: 'Chromium',
|
||||
versionRegex: /Chromium (\S+)/m,
|
||||
binary: ['chromium-browser', 'chromium'],
|
||||
minSupportedVersion: MIN_CHROME_VERSION,
|
||||
},
|
||||
{
|
||||
name: 'chrome',
|
||||
family: 'chromium',
|
||||
channel: 'beta',
|
||||
displayName: 'Chrome Beta',
|
||||
versionRegex: /Google Chrome (\S+) beta/m,
|
||||
binary: 'google-chrome-beta',
|
||||
minSupportedVersion: MIN_CHROME_VERSION,
|
||||
},
|
||||
{
|
||||
name: 'chrome',
|
||||
family: 'chromium',
|
||||
channel: 'canary',
|
||||
displayName: 'Canary',
|
||||
versionRegex: /Google Chrome Canary (\S+)/m,
|
||||
binary: 'google-chrome-canary',
|
||||
minSupportedVersion: MIN_CHROME_VERSION,
|
||||
},
|
||||
{
|
||||
name: 'firefox',
|
||||
family: 'firefox',
|
||||
channel: 'stable',
|
||||
displayName: 'Firefox',
|
||||
// Mozilla Firefox 70.0.1
|
||||
versionRegex: /^Mozilla Firefox ([^\sab]+)$/m,
|
||||
binary: 'firefox',
|
||||
minSupportedVersion: MIN_FIREFOX_VERSION,
|
||||
},
|
||||
{
|
||||
name: 'firefox',
|
||||
family: 'firefox',
|
||||
channel: 'dev',
|
||||
displayName: 'Firefox Developer Edition',
|
||||
// Mozilla Firefox 73.0b12
|
||||
versionRegex: /^Mozilla Firefox (\S+b\S*)$/m,
|
||||
// ubuntu PPAs install it as firefox
|
||||
binary: ['firefox-developer-edition', 'firefox'],
|
||||
minSupportedVersion: MIN_FIREFOX_VERSION,
|
||||
},
|
||||
{
|
||||
name: 'firefox',
|
||||
family: 'firefox',
|
||||
channel: 'nightly',
|
||||
displayName: 'Firefox Nightly',
|
||||
// Mozilla Firefox 74.0a1
|
||||
versionRegex: /^Mozilla Firefox (\S+a\S*)$/m,
|
||||
// ubuntu PPAs install it as firefox-trunk
|
||||
binary: ['firefox-nightly', 'firefox-trunk'],
|
||||
minSupportedVersion: MIN_FIREFOX_VERSION,
|
||||
},
|
||||
{
|
||||
name: 'edge',
|
||||
family: 'chromium',
|
||||
channel: 'stable',
|
||||
displayName: 'Edge',
|
||||
versionRegex: /Microsoft Edge (\S+)/m,
|
||||
binary: ['edge', 'microsoft-edge'],
|
||||
minSupportedVersion: MIN_EDGE_VERSION,
|
||||
},
|
||||
{
|
||||
name: 'edge',
|
||||
family: 'chromium',
|
||||
channel: 'canary',
|
||||
displayName: 'Edge Canary',
|
||||
versionRegex: /Microsoft Edge Canary (\S+)/m,
|
||||
binary: 'edge-canary',
|
||||
minSupportedVersion: MIN_EDGE_VERSION,
|
||||
},
|
||||
{
|
||||
name: 'edge',
|
||||
family: 'chromium',
|
||||
channel: 'beta',
|
||||
displayName: 'Edge Beta',
|
||||
versionRegex: /Microsoft Edge Beta (\S+)/m,
|
||||
binary: 'edge-beta',
|
||||
minSupportedVersion: MIN_EDGE_VERSION,
|
||||
},
|
||||
{
|
||||
name: 'edge',
|
||||
family: 'chromium',
|
||||
channel: 'dev',
|
||||
displayName: 'Edge Dev',
|
||||
versionRegex: /Microsoft Edge Dev (\S+)/m,
|
||||
binary: ['edge-dev', 'microsoft-edge-dev'],
|
||||
minSupportedVersion: MIN_EDGE_VERSION,
|
||||
},
|
||||
]
|
||||
|
||||
export const BROWSER_STATUS = ['closed', 'opening', 'open'] as const
|
||||
|
||||
export type BrowserStatus = typeof BROWSER_STATUS[number]
|
||||
|
||||
@@ -20,10 +20,6 @@ export type { PlatformName } from './platform'
|
||||
|
||||
export {
|
||||
BROWSER_FAMILY,
|
||||
MIN_CHROME_VERSION,
|
||||
MIN_FIREFOX_VERSION,
|
||||
MIN_EDGE_VERSION,
|
||||
browsers,
|
||||
} from './browser'
|
||||
|
||||
export * from './config'
|
||||
|
||||
Reference in New Issue
Block a user