misc: convert @packages/launcher tests from mocha to vitest and always prefer 64-bit install paths to 32-bit (#32656)

* chore: start launcher vitest conversion and conver browsers spec to vitest

* chore: convert darwin spec to vitest

* chore: convert linux spec to vitest

* chore: convert windows spec to vitest

* chore: convert detect spect to vitest

* chore: cleanup unused files

* chore: update browsers orb and replace existing google chrome install

* chore: fix detect spec to use actual implementation of cp.spawn

* chore: convert thennable promise test that was missed in detect spec

* misc: add changelog entry

* chore: remove mock comment

* remove duplicate entry
This commit is contained in:
Bill Glesias
2025-10-09 10:45:48 -04:00
committed by GitHub
parent 24304a62d0
commit efcc12f4ac
25 changed files with 2036 additions and 1692 deletions
+3 -2
View File
@@ -17,7 +17,7 @@ ubuntu-2004-current: &ubuntu-2004-current ubuntu-2004:2024.11.1
ubuntu-2004-older: &ubuntu-2004-older ubuntu-2004:2024.05.1
orbs:
browser-tools: circleci/browser-tools@2.1.1
browser-tools: circleci/browser-tools@2.3.1
defaults: &defaults
parallelism: 1
@@ -563,6 +563,7 @@ commands:
# https://www.ubuntuupdates.org/package/google_chrome/stable/main/base/google-chrome-stable
channel: << parameters.google-chrome-channel >>
chrome_version: << parameters.google-chrome-version >>
replace_existing: true
- when:
condition:
equal: [ 'beta', << parameters.google-chrome-channel>> ]
@@ -1786,7 +1787,7 @@ jobs:
source ./scripts/ensure-node.sh
yarn lerna run types
- sanitize-verify-and-store-mocha-results:
expectedResultCount: 10
expectedResultCount: 9
verify-release-readiness:
<<: *defaults
+8
View File
@@ -1,4 +1,12 @@
<!-- See the ../guides/writing-the-cypress-changelog.md for details on writing the changelog. -->
## 15.4.1
_Released 10/21/2025 (PENDING)_
**Misc:**
Browser detection in Cypress now always prefers 64-bit browser installs to 32-bit browser installs. Addressed in [#32656](https://github.com/cypress-io/cypress/pull/32656).
## 15.4.0
_Released 10/7/2025_
+1 -1
View File
@@ -98,7 +98,7 @@ When migrating some of these projects away from the `ts-node` entry [see `@packa
- [ ] packages/https-proxy
- [x] packages/electron ✅ **COMPLETED**
- [x] packages/icons ✅ **COMPLETED**
- [ ] packages/launcher
- [x] packages/launcher**COMPLETED**
- [ ] packages/net-stubbing
- [x] packages/network ✅ **COMPLETED**
- [ ] packages/packherd-require
@@ -1,123 +0,0 @@
exports['browsers returns the expected list of browsers 1'] = [
{
'name': 'chrome',
'family': 'chromium',
'channel': 'stable',
'displayName': 'Chrome',
'versionRegex': {},
'binary': [
'google-chrome',
'chrome',
'google-chrome-stable',
],
},
{
'name': 'chrome',
'family': 'chromium',
'channel': 'beta',
'displayName': 'Chrome Beta',
'versionRegex': {},
'binary': 'google-chrome-beta',
},
{
'name': 'chrome',
'family': 'chromium',
'channel': 'canary',
'displayName': 'Chrome Canary',
'versionRegex': {},
'binary': 'google-chrome-canary',
},
{
'name': 'chrome-for-testing',
'family': 'chromium',
'channel': 'stable',
'displayName': 'Chrome for Testing',
'versionRegex': {},
'binary': 'chrome',
},
{
'name': 'chromium',
'family': 'chromium',
'channel': 'stable',
'displayName': 'Chromium',
'versionRegex': {},
'binary': [
'chromium-browser',
'chromium',
],
},
{
'name': 'firefox',
'family': 'firefox',
'channel': 'stable',
'displayName': 'Firefox',
'versionRegex': {},
'binary': 'firefox',
},
{
'name': 'firefox',
'family': 'firefox',
'channel': 'dev',
'displayName': 'Firefox Developer Edition',
'versionRegex': {},
'binary': [
'firefox-developer-edition',
'firefox',
],
},
{
'name': 'firefox',
'family': 'firefox',
'channel': 'nightly',
'displayName': 'Firefox Nightly',
'versionRegex': {},
'binary': [
'firefox-nightly',
'firefox-trunk',
],
},
{
'name': 'edge',
'family': 'chromium',
'channel': 'stable',
'displayName': 'Edge',
'versionRegex': {},
'binary': [
'edge',
'microsoft-edge',
],
},
{
'name': 'edge',
'family': 'chromium',
'channel': 'beta',
'displayName': 'Edge Beta',
'versionRegex': {},
'binary': [
'edge-beta',
'microsoft-edge-beta',
],
},
{
'name': 'edge',
'family': 'chromium',
'channel': 'canary',
'displayName': 'Edge Canary',
'versionRegex': {},
'binary': [
'edge-canary',
'microsoft-edge-canary',
],
},
{
'name': 'edge',
'family': 'chromium',
'channel': 'dev',
'displayName': 'Edge Dev',
'versionRegex': {},
'binary': [
'edge-dev',
'microsoft-edge-dev',
],
},
]
@@ -1,219 +0,0 @@
exports['darwin browser detection detects browsers as expected 1'] = [
{
'name': 'chrome',
'family': 'chromium',
'channel': 'stable',
'displayName': 'Chrome',
'versionRegex': {},
'binary': [
'google-chrome',
'chrome',
'google-chrome-stable',
],
'path': '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
'version': 'someVersion',
'findAppParams': {
'appName': 'Google Chrome.app',
'executable': 'Contents/MacOS/Google Chrome',
'bundleId': 'com.google.Chrome',
'versionProperty': 'KSVersion',
},
},
{
'name': 'chrome',
'family': 'chromium',
'channel': 'beta',
'displayName': 'Chrome Beta',
'versionRegex': {},
'binary': 'google-chrome-beta',
'path': '/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta',
'version': 'someVersion',
'findAppParams': {
'appName': 'Google Chrome Beta.app',
'executable': 'Contents/MacOS/Google Chrome Beta',
'bundleId': 'com.google.Chrome.beta',
'versionProperty': 'KSVersion',
},
},
{
'name': 'chrome',
'family': 'chromium',
'channel': 'canary',
'displayName': 'Chrome Canary',
'versionRegex': {},
'binary': 'google-chrome-canary',
'path': '/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary',
'version': 'someVersion',
'findAppParams': {
'appName': 'Google Chrome Canary.app',
'executable': 'Contents/MacOS/Google Chrome Canary',
'bundleId': 'com.google.Chrome.canary',
'versionProperty': 'KSVersion',
},
},
{
'name': 'chrome-for-testing',
'family': 'chromium',
'channel': 'stable',
'displayName': 'Chrome for Testing',
'versionRegex': {},
'binary': 'chrome',
'path': '/Applications/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing',
'version': 'someVersion',
'findAppParams': {
'appName': 'Google Chrome for Testing.app',
'executable': 'Contents/MacOS/Google Chrome for Testing',
'bundleId': 'com.google.chrome.for.testing',
'versionProperty': 'CFBundleShortVersionString',
},
},
{
'name': 'chromium',
'family': 'chromium',
'channel': 'stable',
'displayName': 'Chromium',
'versionRegex': {},
'binary': [
'chromium-browser',
'chromium',
],
'path': '/Applications/Chromium.app/Contents/MacOS/Chromium',
'version': 'someVersion',
'findAppParams': {
'appName': 'Chromium.app',
'executable': 'Contents/MacOS/Chromium',
'bundleId': 'org.chromium.Chromium',
'versionProperty': 'CFBundleShortVersionString',
},
},
{
'name': 'firefox',
'family': 'firefox',
'channel': 'stable',
'displayName': 'Firefox',
'versionRegex': {},
'binary': 'firefox',
'path': '/Applications/Firefox.app/Contents/MacOS/firefox',
'version': 'someVersion',
'findAppParams': {
'appName': 'Firefox.app',
'executable': 'Contents/MacOS/firefox',
'bundleId': 'org.mozilla.firefox',
'versionProperty': 'CFBundleShortVersionString',
},
},
{
'name': 'firefox',
'family': 'firefox',
'channel': 'dev',
'displayName': 'Firefox Developer Edition',
'versionRegex': {},
'binary': [
'firefox-developer-edition',
'firefox',
],
'path': '/Applications/Firefox Developer Edition.app/Contents/MacOS/firefox',
'version': 'someVersion',
'findAppParams': {
'appName': 'Firefox Developer Edition.app',
'executable': 'Contents/MacOS/firefox',
'bundleId': 'org.mozilla.firefoxdeveloperedition',
'versionProperty': 'CFBundleShortVersionString',
},
},
{
'name': 'firefox',
'family': 'firefox',
'channel': 'nightly',
'displayName': 'Firefox Nightly',
'versionRegex': {},
'binary': [
'firefox-nightly',
'firefox-trunk',
],
'path': '/Applications/Firefox Nightly.app/Contents/MacOS/firefox',
'version': 'someVersion',
'findAppParams': {
'appName': 'Firefox Nightly.app',
'executable': 'Contents/MacOS/firefox',
'bundleId': 'org.mozilla.nightly',
'versionProperty': 'CFBundleShortVersionString',
},
},
{
'name': 'edge',
'family': 'chromium',
'channel': 'stable',
'displayName': 'Edge',
'versionRegex': {},
'binary': [
'edge',
'microsoft-edge',
],
'path': '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge',
'version': 'someVersion',
'findAppParams': {
'appName': 'Microsoft Edge.app',
'executable': 'Contents/MacOS/Microsoft Edge',
'bundleId': 'com.microsoft.Edge',
'versionProperty': 'CFBundleShortVersionString',
},
},
{
'name': 'edge',
'family': 'chromium',
'channel': 'beta',
'displayName': 'Edge Beta',
'versionRegex': {},
'binary': [
'edge-beta',
'microsoft-edge-beta',
],
'path': '/Applications/Microsoft Edge Beta.app/Contents/MacOS/Microsoft Edge Beta',
'version': 'someVersion',
'findAppParams': {
'appName': 'Microsoft Edge Beta.app',
'executable': 'Contents/MacOS/Microsoft Edge Beta',
'bundleId': 'com.microsoft.Edge.Beta',
'versionProperty': 'CFBundleShortVersionString',
},
},
{
'name': 'edge',
'family': 'chromium',
'channel': 'canary',
'displayName': 'Edge Canary',
'versionRegex': {},
'binary': [
'edge-canary',
'microsoft-edge-canary',
],
'path': '/Applications/Microsoft Edge Canary.app/Contents/MacOS/Microsoft Edge Canary',
'version': 'someVersion',
'findAppParams': {
'appName': 'Microsoft Edge Canary.app',
'executable': 'Contents/MacOS/Microsoft Edge Canary',
'bundleId': 'com.microsoft.Edge.Canary',
'versionProperty': 'CFBundleShortVersionString',
},
},
{
'name': 'edge',
'family': 'chromium',
'channel': 'dev',
'displayName': 'Edge Dev',
'versionRegex': {},
'binary': [
'edge-dev',
'microsoft-edge-dev',
],
'path': '/Applications/Microsoft Edge Dev.app/Contents/MacOS/Microsoft Edge Dev',
'version': 'someVersion',
'findAppParams': {
'appName': 'Microsoft Edge Dev.app',
'executable': 'Contents/MacOS/Microsoft Edge Dev',
'bundleId': 'com.microsoft.Edge.Dev',
'versionProperty': 'CFBundleShortVersionString',
},
},
]
@@ -1,403 +0,0 @@
exports['windows browser detection detects browsers as expected 1'] = [
{
'name': 'chrome',
'family': 'chromium',
'channel': 'stable',
'displayName': 'Chrome',
'versionRegex': {},
'binary': [
'google-chrome',
'chrome',
'google-chrome-stable',
],
'path': 'C:/Program Files (x86)/Google/Chrome/Application/chrome.exe',
'version': '1.2.3',
'findAppParams': {
'appName': 'Google Chrome.app',
'executable': 'Contents/MacOS/Google Chrome',
'bundleId': 'com.google.Chrome',
'versionProperty': 'KSVersion',
},
},
{
'name': 'chrome',
'family': 'chromium',
'channel': 'beta',
'displayName': 'Chrome Beta',
'versionRegex': {},
'binary': 'google-chrome-beta',
'path': 'C:/Program Files (x86)/Google/Chrome Beta/Application/chrome.exe',
'version': '6.7.8',
'findAppParams': {
'appName': 'Google Chrome Beta.app',
'executable': 'Contents/MacOS/Google Chrome Beta',
'bundleId': 'com.google.Chrome.beta',
'versionProperty': 'KSVersion',
},
},
{
'name': 'chrome',
'family': 'chromium',
'channel': 'canary',
'displayName': 'Chrome Canary',
'versionRegex': {},
'binary': 'google-chrome-canary',
'path': 'C:/Users/flotwig/AppData/Local/Google/Chrome SxS/Application/chrome.exe',
'version': '3.4.5',
'findAppParams': {
'appName': 'Google Chrome Canary.app',
'executable': 'Contents/MacOS/Google Chrome Canary',
'bundleId': 'com.google.Chrome.canary',
'versionProperty': 'KSVersion',
},
},
{
'name': 'chrome-for-testing',
'family': 'chromium',
'channel': 'stable',
'displayName': 'Chrome for Testing',
'versionRegex': {},
'binary': 'chrome',
'path': 'C:/Program Files/Google/Chrome for Testing/chrome.exe',
'version': '1.2.3',
'findAppParams': {
'appName': 'Google Chrome for Testing.app',
'executable': 'Contents/MacOS/Google Chrome for Testing',
'bundleId': 'com.google.chrome.for.testing',
'versionProperty': 'CFBundleShortVersionString',
},
},
{
'name': 'chromium',
'family': 'chromium',
'channel': 'stable',
'displayName': 'Chromium',
'versionRegex': {},
'binary': [
'chromium-browser',
'chromium',
],
'path': 'C:/Program Files (x86)/Google/chrome-win32/chrome.exe',
'version': '2.3.4',
'findAppParams': {
'appName': 'Chromium.app',
'executable': 'Contents/MacOS/Chromium',
'bundleId': 'org.chromium.Chromium',
'versionProperty': 'CFBundleShortVersionString',
},
},
{
'name': 'firefox',
'family': 'firefox',
'channel': 'stable',
'displayName': 'Firefox',
'versionRegex': {},
'binary': 'firefox',
'path': 'C:/Program Files/Mozilla Firefox/firefox.exe',
'version': '72',
'findAppParams': {
'appName': 'Firefox.app',
'executable': 'Contents/MacOS/firefox',
'bundleId': 'org.mozilla.firefox',
'versionProperty': 'CFBundleShortVersionString',
},
},
{
'name': 'firefox',
'family': 'firefox',
'channel': 'dev',
'displayName': 'Firefox Developer Edition',
'versionRegex': {},
'binary': [
'firefox-developer-edition',
'firefox',
],
'path': 'C:/Program Files (x86)/Firefox Developer Edition/firefox.exe',
'version': '73',
'findAppParams': {
'appName': 'Firefox Developer Edition.app',
'executable': 'Contents/MacOS/firefox',
'bundleId': 'org.mozilla.firefoxdeveloperedition',
'versionProperty': 'CFBundleShortVersionString',
},
},
{
'name': 'firefox',
'family': 'firefox',
'channel': 'nightly',
'displayName': 'Firefox Nightly',
'versionRegex': {},
'binary': [
'firefox-nightly',
'firefox-trunk',
],
'path': 'C:/Program Files/Firefox Nightly/firefox.exe',
'version': '74',
'findAppParams': {
'appName': 'Firefox Nightly.app',
'executable': 'Contents/MacOS/firefox',
'bundleId': 'org.mozilla.nightly',
'versionProperty': 'CFBundleShortVersionString',
},
},
{
'name': 'edge',
'family': 'chromium',
'channel': 'stable',
'displayName': 'Edge',
'versionRegex': {},
'binary': [
'edge',
'microsoft-edge',
],
'path': 'C:/Program Files (x86)/Microsoft/Edge/Application/msedge.exe',
'version': '11',
'findAppParams': {
'appName': 'Microsoft Edge.app',
'executable': 'Contents/MacOS/Microsoft Edge',
'bundleId': 'com.microsoft.Edge',
'versionProperty': 'CFBundleShortVersionString',
},
},
{
'name': 'edge',
'family': 'chromium',
'channel': 'beta',
'displayName': 'Edge Beta',
'versionRegex': {},
'binary': [
'edge-beta',
'microsoft-edge-beta',
],
'path': 'C:/Program Files (x86)/Microsoft/Edge Beta/Application/msedge.exe',
'version': '12',
'findAppParams': {
'appName': 'Microsoft Edge Beta.app',
'executable': 'Contents/MacOS/Microsoft Edge Beta',
'bundleId': 'com.microsoft.Edge.Beta',
'versionProperty': 'CFBundleShortVersionString',
},
},
{
'name': 'edge',
'family': 'chromium',
'channel': 'canary',
'displayName': 'Edge Canary',
'versionRegex': {},
'binary': [
'edge-canary',
'microsoft-edge-canary',
],
'path': 'C:/Users/flotwig/AppData/Local/Microsoft/Edge SxS/Application/msedge.exe',
'version': '14',
'findAppParams': {
'appName': 'Microsoft Edge Canary.app',
'executable': 'Contents/MacOS/Microsoft Edge Canary',
'bundleId': 'com.microsoft.Edge.Canary',
'versionProperty': 'CFBundleShortVersionString',
},
},
{
'name': 'edge',
'family': 'chromium',
'channel': 'dev',
'displayName': 'Edge Dev',
'versionRegex': {},
'binary': [
'edge-dev',
'microsoft-edge-dev',
],
'path': 'C:/Program Files (x86)/Microsoft/Edge Dev/Application/msedge.exe',
'version': '13',
'findAppParams': {
'appName': 'Microsoft Edge Dev.app',
'executable': 'Contents/MacOS/Microsoft Edge Dev',
'bundleId': 'com.microsoft.Edge.Dev',
'versionProperty': 'CFBundleShortVersionString',
},
},
]
exports['windows browser detection detects Chrome Beta 64-bit install 1'] = [
{
'name': 'chrome',
'family': 'chromium',
'channel': 'beta',
'displayName': 'Chrome Beta',
'versionRegex': {},
'binary': 'google-chrome-beta',
'path': 'C:/Program Files/Google/Chrome Beta/Application/chrome.exe',
'version': '9.0.1',
'findAppParams': {
'appName': 'Google Chrome Beta.app',
'executable': 'Contents/MacOS/Google Chrome Beta',
'bundleId': 'com.google.Chrome.beta',
'versionProperty': 'KSVersion',
},
},
]
exports['windows browser detection detects Chrome 64-bit install 1'] = [
{
'name': 'chrome',
'family': 'chromium',
'channel': 'stable',
'displayName': 'Chrome',
'versionRegex': {},
'binary': [
'google-chrome',
'chrome',
'google-chrome-stable',
],
'path': 'C:/Program Files/Google/Chrome/Application/chrome.exe',
'version': '4.4.4',
'findAppParams': {
'appName': 'Google Chrome.app',
'executable': 'Contents/MacOS/Google Chrome',
'bundleId': 'com.google.Chrome',
'versionProperty': 'KSVersion',
},
},
]
exports['windows browser detection detects Chrome for Testing 32-bit install 1'] = [
{
'name': 'chrome-for-testing',
'family': 'chromium',
'channel': 'stable',
'displayName': 'Chrome for Testing',
'versionRegex': {},
'binary': 'chrome',
'path': 'C:/Program Files (x86)/Google/Chrome for Testing/chrome.exe',
'version': '5.5.5',
'findAppParams': {
'appName': 'Google Chrome for Testing.app',
'executable': 'Contents/MacOS/Google Chrome for Testing',
'bundleId': 'com.google.chrome.for.testing',
'versionProperty': 'CFBundleShortVersionString',
},
},
]
exports['windows browser detection detects Firefox local installs 1'] = [
{
'name': 'firefox',
'family': 'firefox',
'channel': 'stable',
'displayName': 'Firefox',
'versionRegex': {},
'binary': 'firefox',
'path': 'C:/Users/flotwig/AppData/Local/Mozilla Firefox/firefox.exe',
'version': '100',
'findAppParams': {
'appName': 'Firefox.app',
'executable': 'Contents/MacOS/firefox',
'bundleId': 'org.mozilla.firefox',
'versionProperty': 'CFBundleShortVersionString',
},
},
{
'name': 'firefox',
'family': 'firefox',
'channel': 'dev',
'displayName': 'Firefox Developer Edition',
'versionRegex': {},
'binary': [
'firefox-developer-edition',
'firefox',
],
'path': 'C:/Users/flotwig/AppData/Local/Firefox Developer Edition/firefox.exe',
'version': '300',
'findAppParams': {
'appName': 'Firefox Developer Edition.app',
'executable': 'Contents/MacOS/firefox',
'bundleId': 'org.mozilla.firefoxdeveloperedition',
'versionProperty': 'CFBundleShortVersionString',
},
},
{
'name': 'firefox',
'family': 'firefox',
'channel': 'nightly',
'displayName': 'Firefox Nightly',
'versionRegex': {},
'binary': [
'firefox-nightly',
'firefox-trunk',
],
'path': 'C:/Users/flotwig/AppData/Local/Firefox Nightly/firefox.exe',
'version': '200',
'findAppParams': {
'appName': 'Firefox Nightly.app',
'executable': 'Contents/MacOS/firefox',
'bundleId': 'org.mozilla.nightly',
'versionProperty': 'CFBundleShortVersionString',
},
},
]
exports['windows browser detection detects Chromium 64-bit install 1'] = [
{
'name': 'chromium',
'family': 'chromium',
'channel': 'stable',
'displayName': 'Chromium',
'versionRegex': {},
'binary': [
'chromium-browser',
'chromium',
],
'path': 'C:/Program Files/Google/chrome-win/chrome.exe',
'version': '6.6.6',
'findAppParams': {
'appName': 'Chromium.app',
'executable': 'Contents/MacOS/Chromium',
'bundleId': 'org.chromium.Chromium',
'versionProperty': 'CFBundleShortVersionString',
},
},
]
exports['windows browser detection detects Chromium 32-bit install in Chromium folder 1'] = [
{
'name': 'chromium',
'family': 'chromium',
'channel': 'stable',
'displayName': 'Chromium',
'versionRegex': {},
'binary': [
'chromium-browser',
'chromium',
],
'path': 'C:/Program Files (x86)/Google/Chromium/chrome.exe',
'version': '7.7.7',
'findAppParams': {
'appName': 'Chromium.app',
'executable': 'Contents/MacOS/Chromium',
'bundleId': 'org.chromium.Chromium',
'versionProperty': 'CFBundleShortVersionString',
},
},
]
exports['windows browser detection detects Chromium 64-bit install in Chromium folder 1'] = [
{
'name': 'chromium',
'family': 'chromium',
'channel': 'stable',
'displayName': 'Chromium',
'versionRegex': {},
'binary': [
'chromium-browser',
'chromium',
],
'path': 'C:/Program Files/Google/Chromium/chrome.exe',
'version': '8.8.8',
'findAppParams': {
'appName': 'Chromium.app',
'executable': 'Contents/MacOS/Chromium',
'bundleId': 'org.chromium.Chromium',
'versionProperty': 'CFBundleShortVersionString',
},
},
]
+3 -3
View File
@@ -1,9 +1,9 @@
import Debug from 'debug'
import { notInstalledErr } from '../errors'
import { utils } from '../utils'
import * as fs from 'fs-extra'
import * as path from 'path'
import * as plist from 'plist'
import fs from 'fs-extra'
import path from 'path'
import plist from 'plist'
const debugVerbose = Debug('cypress-verbose:launcher:darwin:util')
+6 -8
View File
@@ -1,4 +1,4 @@
import * as fse from 'fs-extra'
import fs from 'fs-extra'
import winVersionInfo from 'win-version-info'
import os from 'os'
import { join, normalize, win32 } from 'path'
@@ -13,23 +13,23 @@ const debugVerbose = Debug('cypress-verbose:launcher:windows')
function formFullAppPath (name: string) {
return [
`C:/Program Files (x86)/Google/Chrome/Application/${name}.exe`,
`C:/Program Files/Google/Chrome/Application/${name}.exe`,
`C:/Program Files (x86)/Google/Chrome/Application/${name}.exe`,
].map(normalize)
}
function formChromeBetaAppPath () {
return [
'C:/Program Files (x86)/Google/Chrome Beta/Application/chrome.exe',
'C:/Program Files/Google/Chrome Beta/Application/chrome.exe',
'C:/Program Files (x86)/Google/Chrome Beta/Application/chrome.exe',
].map(normalize)
}
function formChromiumAppPath () {
return [
'C:/Program Files (x86)/Google/chrome-win32/chrome.exe',
'C:/Program Files/Google/chrome-win/chrome.exe',
'C:/Program Files/Google/Chromium/chrome.exe',
'C:/Program Files (x86)/Google/chrome-win32/chrome.exe',
'C:/Program Files (x86)/Google/Chromium/chrome.exe',
].map(normalize)
}
@@ -144,7 +144,7 @@ function getWindowsBrowser (browser: Browser): Promise<FoundBrowser> {
let path = doubleEscape(exePath)
return fse.pathExists(path)
return fs.pathExists(path)
.then((exists) => {
debugVerbose('found %s ? %o', path, { exists })
@@ -152,9 +152,7 @@ function getWindowsBrowser (browser: Browser): Promise<FoundBrowser> {
return tryNextExePath()
}
// Use module.exports.getVersionString here, rather than our local reference
// to that variable so that the tests can easily mock it
return module.exports.getVersionString(path).then((version) => {
return getVersionString(path).then((version) => {
debug('got version string for %s: %o', browser.name, { exePath, version })
return {
+4 -7
View File
@@ -11,7 +11,8 @@
"lint": "eslint --ext .js,.jsx,.ts,.tsx,.json, .",
"size": "t=\"cypress-v0.0.0.tgz\"; yarn pack --filename \"${t}\"; wc -c \"cli/${t}\"; tar tvf \"${t}\"; rm \"${t}\";",
"test": "yarn test-unit",
"test-unit": "mocha --reporter mocha-multi-reporters --reporter-options configFile=../../mocha-reporter-config.json",
"test-debug": "vitest --inspect-brk --no-file-parallelism --test-timeout=0",
"test-unit": "vitest run",
"tslint": "tslint --config ../ts/tslint.json --project ."
},
"dependencies": {
@@ -29,13 +30,9 @@
"@packages/data-context": "0.0.0-development",
"@packages/ts": "0.0.0-development",
"@packages/types": "0.0.0-development",
"chai": "3.5.0",
"chai-as-promised": "7.1.1",
"mocha": "3.5.3",
"mock-fs": "5.4.0",
"sinon": "^10.0.0",
"sinon-chai": "3.7.0",
"typescript": "~5.4.5"
"typescript": "~5.4.5",
"vitest": "^3.2.4"
},
"files": [
"index.js",
-4
View File
@@ -1,4 +0,0 @@
test/unit
--compilers ts:@packages/ts/register
--timeout 10000
--recursive
-10
View File
@@ -1,10 +0,0 @@
import chai from 'chai'
import sinon from 'sinon'
import 'sinon-chai'
import chaiAsPromised from 'chai-as-promised'
chai.use(chaiAsPromised)
afterEach(() => {
sinon.restore()
})
@@ -0,0 +1,131 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`browsers > returns the expected list of browsers 1`] = `
[
{
"binary": [
"google-chrome",
"chrome",
"google-chrome-stable",
],
"channel": "stable",
"displayName": "Chrome",
"family": "chromium",
"name": "chrome",
"validator": [Function],
"versionRegex": /Google Chrome\\(\\?! for Testing\\) \\(\\\\S\\+\\)/m,
},
{
"binary": "google-chrome-beta",
"channel": "beta",
"displayName": "Chrome Beta",
"family": "chromium",
"name": "chrome",
"versionRegex": /Google Chrome \\(\\\\S\\+\\) beta/m,
},
{
"binary": "google-chrome-canary",
"channel": "canary",
"displayName": "Chrome Canary",
"family": "chromium",
"name": "chrome",
"versionRegex": /Google Chrome Canary \\(\\\\S\\+\\)/m,
},
{
"binary": "chrome",
"channel": "stable",
"displayName": "Chrome for Testing",
"family": "chromium",
"name": "chrome-for-testing",
"versionRegex": /Google Chrome for Testing \\(\\\\S\\+\\)/m,
},
{
"binary": [
"chromium-browser",
"chromium",
],
"channel": "stable",
"displayName": "Chromium",
"family": "chromium",
"name": "chromium",
"versionRegex": /Chromium \\(\\\\S\\+\\)/m,
},
{
"binary": "firefox",
"channel": "stable",
"displayName": "Firefox",
"family": "firefox",
"name": "firefox",
"validator": [Function],
"versionRegex": /\\^Mozilla Firefox \\(\\[\\^\\\\sab\\]\\+\\)\\$/m,
},
{
"binary": [
"firefox-developer-edition",
"firefox",
],
"channel": "dev",
"displayName": "Firefox Developer Edition",
"family": "firefox",
"name": "firefox",
"validator": [Function],
"versionRegex": /\\^Mozilla Firefox \\(\\\\S\\+b\\\\S\\*\\)\\$/m,
},
{
"binary": [
"firefox-nightly",
"firefox-trunk",
],
"channel": "nightly",
"displayName": "Firefox Nightly",
"family": "firefox",
"name": "firefox",
"validator": [Function],
"versionRegex": /\\^Mozilla Firefox \\(\\\\S\\+a\\\\S\\*\\)\\$/m,
},
{
"binary": [
"edge",
"microsoft-edge",
],
"channel": "stable",
"displayName": "Edge",
"family": "chromium",
"name": "edge",
"versionRegex": /Microsoft Edge \\(\\\\S\\+\\)/im,
},
{
"binary": [
"edge-beta",
"microsoft-edge-beta",
],
"channel": "beta",
"displayName": "Edge Beta",
"family": "chromium",
"name": "edge",
"versionRegex": /Microsoft Edge\\.\\+\\?\\(\\\\S\\*\\(\\?= beta\\)\\|\\(\\?<=beta \\)\\\\S\\*\\)/im,
},
{
"binary": [
"edge-canary",
"microsoft-edge-canary",
],
"channel": "canary",
"displayName": "Edge Canary",
"family": "chromium",
"name": "edge",
"versionRegex": /Microsoft Edge\\.\\+\\?\\(\\\\S\\*\\(\\?= canary\\)\\|\\(\\?<=canary \\)\\\\S\\*\\)/im,
},
{
"binary": [
"edge-dev",
"microsoft-edge-dev",
],
"channel": "dev",
"displayName": "Edge Dev",
"family": "chromium",
"name": "edge",
"versionRegex": /Microsoft Edge\\.\\+\\?\\(\\\\S\\*\\(\\?= dev\\)\\|\\(\\?<=dev \\)\\\\S\\*\\)/im,
},
]
`;
@@ -0,0 +1,227 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`darwin browser detection > detects browsers as expected 1`] = `
[
{
"binary": [
"google-chrome",
"chrome",
"google-chrome-stable",
],
"channel": "stable",
"displayName": "Chrome",
"family": "chromium",
"findAppParams": {
"appName": "Google Chrome.app",
"bundleId": "com.google.Chrome",
"executable": "Contents/MacOS/Google Chrome",
"versionProperty": "KSVersion",
},
"name": "chrome",
"path": "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
"validator": [Function],
"version": "someVersion",
"versionRegex": /Google Chrome\\(\\?! for Testing\\) \\(\\\\S\\+\\)/m,
},
{
"binary": "google-chrome-beta",
"channel": "beta",
"displayName": "Chrome Beta",
"family": "chromium",
"findAppParams": {
"appName": "Google Chrome Beta.app",
"bundleId": "com.google.Chrome.beta",
"executable": "Contents/MacOS/Google Chrome Beta",
"versionProperty": "KSVersion",
},
"name": "chrome",
"path": "/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta",
"version": "someVersion",
"versionRegex": /Google Chrome \\(\\\\S\\+\\) beta/m,
},
{
"binary": "google-chrome-canary",
"channel": "canary",
"displayName": "Chrome Canary",
"family": "chromium",
"findAppParams": {
"appName": "Google Chrome Canary.app",
"bundleId": "com.google.Chrome.canary",
"executable": "Contents/MacOS/Google Chrome Canary",
"versionProperty": "KSVersion",
},
"name": "chrome",
"path": "/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary",
"version": "someVersion",
"versionRegex": /Google Chrome Canary \\(\\\\S\\+\\)/m,
},
{
"binary": "chrome",
"channel": "stable",
"displayName": "Chrome for Testing",
"family": "chromium",
"findAppParams": {
"appName": "Google Chrome for Testing.app",
"bundleId": "com.google.chrome.for.testing",
"executable": "Contents/MacOS/Google Chrome for Testing",
"versionProperty": "CFBundleShortVersionString",
},
"name": "chrome-for-testing",
"path": "/Applications/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing",
"version": "someVersion",
"versionRegex": /Google Chrome for Testing \\(\\\\S\\+\\)/m,
},
{
"binary": [
"chromium-browser",
"chromium",
],
"channel": "stable",
"displayName": "Chromium",
"family": "chromium",
"findAppParams": {
"appName": "Chromium.app",
"bundleId": "org.chromium.Chromium",
"executable": "Contents/MacOS/Chromium",
"versionProperty": "CFBundleShortVersionString",
},
"name": "chromium",
"path": "/Applications/Chromium.app/Contents/MacOS/Chromium",
"version": "someVersion",
"versionRegex": /Chromium \\(\\\\S\\+\\)/m,
},
{
"binary": "firefox",
"channel": "stable",
"displayName": "Firefox",
"family": "firefox",
"findAppParams": {
"appName": "Firefox.app",
"bundleId": "org.mozilla.firefox",
"executable": "Contents/MacOS/firefox",
"versionProperty": "CFBundleShortVersionString",
},
"name": "firefox",
"path": "/Applications/Firefox.app/Contents/MacOS/firefox",
"validator": [Function],
"version": "someVersion",
"versionRegex": /\\^Mozilla Firefox \\(\\[\\^\\\\sab\\]\\+\\)\\$/m,
},
{
"binary": [
"firefox-developer-edition",
"firefox",
],
"channel": "dev",
"displayName": "Firefox Developer Edition",
"family": "firefox",
"findAppParams": {
"appName": "Firefox Developer Edition.app",
"bundleId": "org.mozilla.firefoxdeveloperedition",
"executable": "Contents/MacOS/firefox",
"versionProperty": "CFBundleShortVersionString",
},
"name": "firefox",
"path": "/Applications/Firefox Developer Edition.app/Contents/MacOS/firefox",
"validator": [Function],
"version": "someVersion",
"versionRegex": /\\^Mozilla Firefox \\(\\\\S\\+b\\\\S\\*\\)\\$/m,
},
{
"binary": [
"firefox-nightly",
"firefox-trunk",
],
"channel": "nightly",
"displayName": "Firefox Nightly",
"family": "firefox",
"findAppParams": {
"appName": "Firefox Nightly.app",
"bundleId": "org.mozilla.nightly",
"executable": "Contents/MacOS/firefox",
"versionProperty": "CFBundleShortVersionString",
},
"name": "firefox",
"path": "/Applications/Firefox Nightly.app/Contents/MacOS/firefox",
"validator": [Function],
"version": "someVersion",
"versionRegex": /\\^Mozilla Firefox \\(\\\\S\\+a\\\\S\\*\\)\\$/m,
},
{
"binary": [
"edge",
"microsoft-edge",
],
"channel": "stable",
"displayName": "Edge",
"family": "chromium",
"findAppParams": {
"appName": "Microsoft Edge.app",
"bundleId": "com.microsoft.Edge",
"executable": "Contents/MacOS/Microsoft Edge",
"versionProperty": "CFBundleShortVersionString",
},
"name": "edge",
"path": "/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge",
"version": "someVersion",
"versionRegex": /Microsoft Edge \\(\\\\S\\+\\)/im,
},
{
"binary": [
"edge-beta",
"microsoft-edge-beta",
],
"channel": "beta",
"displayName": "Edge Beta",
"family": "chromium",
"findAppParams": {
"appName": "Microsoft Edge Beta.app",
"bundleId": "com.microsoft.Edge.Beta",
"executable": "Contents/MacOS/Microsoft Edge Beta",
"versionProperty": "CFBundleShortVersionString",
},
"name": "edge",
"path": "/Applications/Microsoft Edge Beta.app/Contents/MacOS/Microsoft Edge Beta",
"version": "someVersion",
"versionRegex": /Microsoft Edge\\.\\+\\?\\(\\\\S\\*\\(\\?= beta\\)\\|\\(\\?<=beta \\)\\\\S\\*\\)/im,
},
{
"binary": [
"edge-canary",
"microsoft-edge-canary",
],
"channel": "canary",
"displayName": "Edge Canary",
"family": "chromium",
"findAppParams": {
"appName": "Microsoft Edge Canary.app",
"bundleId": "com.microsoft.Edge.Canary",
"executable": "Contents/MacOS/Microsoft Edge Canary",
"versionProperty": "CFBundleShortVersionString",
},
"name": "edge",
"path": "/Applications/Microsoft Edge Canary.app/Contents/MacOS/Microsoft Edge Canary",
"version": "someVersion",
"versionRegex": /Microsoft Edge\\.\\+\\?\\(\\\\S\\*\\(\\?= canary\\)\\|\\(\\?<=canary \\)\\\\S\\*\\)/im,
},
{
"binary": [
"edge-dev",
"microsoft-edge-dev",
],
"channel": "dev",
"displayName": "Edge Dev",
"family": "chromium",
"findAppParams": {
"appName": "Microsoft Edge Dev.app",
"bundleId": "com.microsoft.Edge.Dev",
"executable": "Contents/MacOS/Microsoft Edge Dev",
"versionProperty": "CFBundleShortVersionString",
},
"name": "edge",
"path": "/Applications/Microsoft Edge Dev.app/Contents/MacOS/Microsoft Edge Dev",
"version": "someVersion",
"versionRegex": /Microsoft Edge\\.\\+\\?\\(\\\\S\\*\\(\\?= dev\\)\\|\\(\\?<=dev \\)\\\\S\\*\\)/im,
},
]
`;
@@ -0,0 +1,291 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`windows browser detection > detects Chrome 64-bit install 1`] = `
{
"binary": [
"google-chrome",
"chrome",
"google-chrome-stable",
],
"channel": "stable",
"displayName": "Chrome",
"family": "chromium",
"name": "chrome",
"path": "C:/Program Files/Google/Chrome/Application/chrome.exe",
"validator": [Function],
"version": "4.4.4",
"versionRegex": /Google Chrome\\(\\?! for Testing\\) \\(\\\\S\\+\\)/m,
}
`;
exports[`windows browser detection > detects Chrome Beta 64-bit install 1`] = `
{
"binary": "google-chrome-beta",
"channel": "beta",
"displayName": "Chrome Beta",
"family": "chromium",
"name": "chrome",
"path": "C:/Program Files/Google/Chrome Beta/Application/chrome.exe",
"version": "9.0.1",
"versionRegex": /Google Chrome \\(\\\\S\\+\\) beta/m,
}
`;
exports[`windows browser detection > detects Chrome for Testing 32-bit install 1`] = `
{
"binary": "chrome",
"channel": "stable",
"displayName": "Chrome for Testing",
"family": "chromium",
"name": "chrome-for-testing",
"path": "C:/Program Files (x86)/Google/Chrome for Testing/chrome.exe",
"version": "5.5.5",
"versionRegex": /Google Chrome for Testing \\(\\\\S\\+\\)/m,
}
`;
exports[`windows browser detection > detects Chromium 32-bit install in Chromium folder 1`] = `
{
"binary": [
"chromium-browser",
"chromium",
],
"channel": "stable",
"displayName": "Chromium",
"family": "chromium",
"name": "chromium",
"path": "C:/Program Files (x86)/Google/Chromium/chrome.exe",
"version": "7.7.7",
"versionRegex": /Chromium \\(\\\\S\\+\\)/m,
}
`;
exports[`windows browser detection > detects Chromium 64-bit install 1`] = `
{
"binary": [
"chromium-browser",
"chromium",
],
"channel": "stable",
"displayName": "Chromium",
"family": "chromium",
"name": "chromium",
"path": "C:/Program Files/Google/chrome-win/chrome.exe",
"version": "6.6.6",
"versionRegex": /Chromium \\(\\\\S\\+\\)/m,
}
`;
exports[`windows browser detection > detects Chromium 64-bit install in Chromium folder 1`] = `
{
"binary": [
"chromium-browser",
"chromium",
],
"channel": "stable",
"displayName": "Chromium",
"family": "chromium",
"name": "chromium",
"path": "C:/Program Files/Google/Chromium/chrome.exe",
"version": "8.8.8",
"versionRegex": /Chromium \\(\\\\S\\+\\)/m,
}
`;
exports[`windows browser detection > detects Firefox local installs 1`] = `
[
{
"binary": "firefox",
"channel": "stable",
"displayName": "Firefox",
"family": "firefox",
"name": "firefox",
"path": "C:/Users/flotwig/AppData/Local/Mozilla Firefox/firefox.exe",
"validator": [Function],
"version": "100",
"versionRegex": /\\^Mozilla Firefox \\(\\[\\^\\\\sab\\]\\+\\)\\$/m,
},
{
"binary": [
"firefox-developer-edition",
"firefox",
],
"channel": "dev",
"displayName": "Firefox Developer Edition",
"family": "firefox",
"name": "firefox",
"path": "C:/Users/flotwig/AppData/Local/Firefox Developer Edition/firefox.exe",
"validator": [Function],
"version": "300",
"versionRegex": /\\^Mozilla Firefox \\(\\\\S\\+b\\\\S\\*\\)\\$/m,
},
{
"binary": [
"firefox-nightly",
"firefox-trunk",
],
"channel": "nightly",
"displayName": "Firefox Nightly",
"family": "firefox",
"name": "firefox",
"path": "C:/Users/flotwig/AppData/Local/Firefox Nightly/firefox.exe",
"validator": [Function],
"version": "200",
"versionRegex": /\\^Mozilla Firefox \\(\\\\S\\+a\\\\S\\*\\)\\$/m,
},
]
`;
exports[`windows browser detection > detects browsers as expected 1`] = `
[
{
"binary": [
"google-chrome",
"chrome",
"google-chrome-stable",
],
"channel": "stable",
"displayName": "Chrome",
"family": "chromium",
"name": "chrome",
"path": "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe",
"validator": [Function],
"version": "1.2.3",
"versionRegex": /Google Chrome\\(\\?! for Testing\\) \\(\\\\S\\+\\)/m,
},
{
"binary": "google-chrome-beta",
"channel": "beta",
"displayName": "Chrome Beta",
"family": "chromium",
"name": "chrome",
"path": "C:/Program Files (x86)/Google/Chrome Beta/Application/chrome.exe",
"version": "6.7.8",
"versionRegex": /Google Chrome \\(\\\\S\\+\\) beta/m,
},
{
"binary": "google-chrome-canary",
"channel": "canary",
"displayName": "Chrome Canary",
"family": "chromium",
"name": "chrome",
"path": "C:/Users/flotwig/AppData/Local/Google/Chrome SxS/Application/chrome.exe",
"version": "3.4.5",
"versionRegex": /Google Chrome Canary \\(\\\\S\\+\\)/m,
},
{
"binary": "chrome",
"channel": "stable",
"displayName": "Chrome for Testing",
"family": "chromium",
"name": "chrome-for-testing",
"path": "C:/Program Files/Google/Chrome for Testing/chrome.exe",
"version": "1.2.3",
"versionRegex": /Google Chrome for Testing \\(\\\\S\\+\\)/m,
},
{
"binary": [
"chromium-browser",
"chromium",
],
"channel": "stable",
"displayName": "Chromium",
"family": "chromium",
"name": "chromium",
"path": "C:/Program Files/Google/chrome-win/chrome.exe",
"version": "2.3.4",
"versionRegex": /Chromium \\(\\\\S\\+\\)/m,
},
{
"binary": "firefox",
"channel": "stable",
"displayName": "Firefox",
"family": "firefox",
"name": "firefox",
"path": "C:/Program Files/Mozilla Firefox/firefox.exe",
"validator": [Function],
"version": "72",
"versionRegex": /\\^Mozilla Firefox \\(\\[\\^\\\\sab\\]\\+\\)\\$/m,
},
{
"binary": [
"firefox-developer-edition",
"firefox",
],
"channel": "dev",
"displayName": "Firefox Developer Edition",
"family": "firefox",
"name": "firefox",
"path": "C:/Program Files (x86)/Firefox Developer Edition/firefox.exe",
"validator": [Function],
"version": "73",
"versionRegex": /\\^Mozilla Firefox \\(\\\\S\\+b\\\\S\\*\\)\\$/m,
},
{
"binary": [
"firefox-nightly",
"firefox-trunk",
],
"channel": "nightly",
"displayName": "Firefox Nightly",
"family": "firefox",
"name": "firefox",
"path": "C:/Program Files/Firefox Nightly/firefox.exe",
"validator": [Function],
"version": "74",
"versionRegex": /\\^Mozilla Firefox \\(\\\\S\\+a\\\\S\\*\\)\\$/m,
},
{
"binary": [
"edge",
"microsoft-edge",
],
"channel": "stable",
"displayName": "Edge",
"family": "chromium",
"name": "edge",
"path": "C:/Program Files (x86)/Microsoft/Edge/Application/msedge.exe",
"version": "11",
"versionRegex": /Microsoft Edge \\(\\\\S\\+\\)/im,
},
{
"binary": [
"edge-beta",
"microsoft-edge-beta",
],
"channel": "beta",
"displayName": "Edge Beta",
"family": "chromium",
"name": "edge",
"path": "C:/Program Files (x86)/Microsoft/Edge Beta/Application/msedge.exe",
"version": "12",
"versionRegex": /Microsoft Edge\\.\\+\\?\\(\\\\S\\*\\(\\?= beta\\)\\|\\(\\?<=beta \\)\\\\S\\*\\)/im,
},
{
"binary": [
"edge-canary",
"microsoft-edge-canary",
],
"channel": "canary",
"displayName": "Edge Canary",
"family": "chromium",
"name": "edge",
"path": "C:/Users/flotwig/AppData/Local/Microsoft/Edge SxS/Application/msedge.exe",
"version": "14",
"versionRegex": /Microsoft Edge\\.\\+\\?\\(\\\\S\\*\\(\\?= canary\\)\\|\\(\\?<=canary \\)\\\\S\\*\\)/im,
},
{
"binary": [
"edge-dev",
"microsoft-edge-dev",
],
"channel": "dev",
"displayName": "Edge Dev",
"family": "chromium",
"name": "edge",
"path": "C:/Program Files (x86)/Microsoft/Edge Dev/Application/msedge.exe",
"version": "13",
"versionRegex": /Microsoft Edge\\.\\+\\?\\(\\\\S\\*\\(\\?= dev\\)\\|\\(\\?<=dev \\)\\\\S\\*\\)/im,
},
]
`;
@@ -1,18 +1,17 @@
import { describe, it, expect } from 'vitest'
import _ from 'lodash'
import { knownBrowsers } from '../../lib/known-browsers'
import { expect } from 'chai'
const snapshot = require('snap-shot-it')
describe('browsers', () => {
it('returns the expected list of browsers', () => {
snapshot(knownBrowsers)
expect(knownBrowsers).toMatchSnapshot()
})
// https://github.com/cypress-io/cypress/issues/6669
it('exports multiline versionRegexes', () => {
expect(_.every(knownBrowsers.map(({ versionRegex }) => {
return versionRegex.multiline
}))).to.be.true
}))).toBe(true)
})
describe('browser.validator', () => {
@@ -21,7 +20,7 @@ describe('browsers', () => {
path: '/path/to/firefox',
}
context('validator defined', () => {
describe('validator defined', () => {
it('when conditions met: marks browser as not supported and generates warning message', () => {
const foundBrowser = {
...firefoxBrowser,
@@ -43,8 +42,8 @@ describe('browsers', () => {
const result = foundBrowser.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.')
expect(result.isSupported).toBe(false)
expect(result.warningMessage).toContain('Cypress does not support running Firefox version 101 on Windows due to a blocking bug in Firefox.')
})
it('when conditions not met: marks browser as not supported and generates warning message', () => {
@@ -68,8 +67,8 @@ describe('browsers', () => {
const result = foundBrowser.validator(foundBrowser, 'win32')
expect(result.isSupported).to.be.true
expect(result.warningMessage).to.be.undefined
expect(result.isSupported).toBe(true)
expect(result.warningMessage).toBeUndefined()
})
describe('firefox validation', () => {
@@ -85,8 +84,8 @@ describe('browsers', () => {
displayName: 'Firefox',
})
expect(result.isSupported).to.be.false
expect(result.warningMessage).to.equal('Cypress does not support running Firefox version 134 due to lack of WebDriver BiDi support. To use Firefox with Cypress, install version 135 or newer.')
expect(result.isSupported).toBe(false)
expect(result.warningMessage).toEqual('Cypress does not support running Firefox version 134 due to lack of WebDriver BiDi support. To use Firefox with Cypress, install version 135 or newer.')
})
})
})
+208
View File
@@ -0,0 +1,208 @@
import { describe, it, expect, beforeEach, vi } from 'vitest'
import os from 'os'
import cp from 'child_process'
import fs from 'fs-extra'
import { PassThrough } from 'stream'
import { FoundBrowser } from '@packages/types'
import * as darwinHelper from '../../lib/darwin'
import * as linuxHelper from '../../lib/linux'
import * as darwinUtil from '../../lib/darwin/util'
import { launch } from '../../lib/browsers'
import { knownBrowsers } from '../../lib/known-browsers'
vi.mock('os', async (importActual) => {
const actual = await importActual()
return {
default: {
// @ts-expect-error
...actual.default,
arch: vi.fn(),
platform: vi.fn(),
},
}
})
vi.mock('fs-extra', async (importActual) => {
const actual = await importActual()
return {
default: {
// @ts-expect-error
...actual.default,
readFile: vi.fn(),
},
}
})
vi.mock('child_process', async (importActual) => {
const actual = await importActual()
return {
default: {
// @ts-expect-error
...actual.default,
spawn: vi.fn(),
},
}
})
function generatePlist (key, value) {
return `
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>${key}</key>
<string>${value}</string>
</dict>
</plist>
`
}
describe('darwin browser detection', () => {
beforeEach(() => {
vi.unstubAllEnvs()
vi.resetAllMocks()
vi.mocked(fs.readFile).mockRejectedValue({ code: 'ENOENT' })
})
it('detects browsers as expected', async () => {
// this test uses the macOS detectors to stub out the expected calls
const flatFindAppParams: darwinUtil.FindAppParams[] = []
for (const browser in darwinHelper.browsers) {
for (const channel in darwinHelper.browsers[browser]) {
flatFindAppParams.push(darwinHelper.browsers[browser][channel])
}
}
// @ts-expect-error
vi.mocked(fs.readFile).mockImplementation((file: string, _options: any): Promise<string> => {
const foundAppParams = flatFindAppParams.find((findAppParams) => `/Applications/${findAppParams.appName}/Contents/Info.plist` === file)
if (foundAppParams) {
return Promise.resolve(generatePlist(foundAppParams.versionProperty, 'someVersion'))
}
throw new Error('File not found')
})
const mappedBrowsers = []
for (const browser of knownBrowsers) {
const foundBrowser = await darwinHelper.detect(browser)
const findAppParams = darwinHelper.browsers[browser.name][browser.channel]
mappedBrowsers.push({
...browser,
...foundBrowser,
findAppParams,
})
}
expect(mappedBrowsers).toMatchSnapshot()
})
it('getVersionString is re-exported from linuxHelper', () => {
expect(darwinHelper.getVersionString).toEqual(linuxHelper.getVersionString)
})
describe('forces correct architecture', () => {
beforeEach(() => {
vi.unstubAllEnvs()
vi.stubEnv('env2', 'false')
vi.stubEnv('env3', 'true')
vi.mocked(os.platform).mockReturnValue('darwin')
vi.mocked(cp.spawn).mockImplementation(() => {
const mock: any = {
on: vi.fn(),
once: vi.fn(),
stdout: new PassThrough(),
stderr: new PassThrough(),
kill: vi.fn(),
}
mock.on.mockImplementation((event: string, callback: (...args: any[]) => void) => {
if (event === 'exit') {
setTimeout(() => callback(), 0)
}
if (event === 'close') {
setTimeout(() => callback(), 0)
}
})
mock.stderr.end()
mock.stdout.end()
return mock as cp.ChildProcess
})
})
describe('in version detection', () => {
it('uses arch and ARCHPREFERENCE on arm64', async () => {
vi.mocked(os.arch).mockReturnValue('arm64')
// this will error since we aren't setting stdout
await (darwinHelper.detect(knownBrowsers[0]).catch(() => {}))
expect(cp.spawn).toHaveBeenNthCalledWith(1, 'arch', [knownBrowsers[0].binary, '--version'], expect.objectContaining({
env: expect.objectContaining({
ARCHPREFERENCE: 'arm64,x86_64',
env2: 'false',
env3: 'true',
}),
}))
})
it('does not use `arch` on x64', async () => {
vi.mocked(os.arch).mockReturnValue('x64')
// this will error since we aren't setting stdout
await (darwinHelper.detect(knownBrowsers[0]).catch(() => {}))
expect(cp.spawn).toHaveBeenNthCalledWith(1, knownBrowsers[0].binary, ['--version'], expect.objectContaining({
env: expect.objectContaining({
env2: 'false',
env3: 'true',
}),
}))
})
})
describe('in browser launching', () => {
it('uses arch and ARCHPREFERENCE on arm64', async () => {
vi.mocked(os.arch).mockReturnValue('arm64')
await launch({ path: 'chrome' } as unknown as FoundBrowser, 'url', 123, ['arg1'], { env1: 'true', env2: 'true' })
expect(cp.spawn).toHaveBeenNthCalledWith(1, 'arch', ['chrome', 'url', 'arg1'], expect.objectContaining({
env: expect.objectContaining({
ARCHPREFERENCE: 'arm64,x86_64',
env1: 'true',
env2: 'false',
env3: 'true',
}),
}))
})
it('does not use `arch` on x64', async () => {
vi.mocked(os.arch).mockReturnValue('x64')
await launch({ path: 'chrome' } as unknown as FoundBrowser, 'url', 123, ['arg1'], { env1: 'true', env2: 'true' })
expect(cp.spawn).toHaveBeenNthCalledWith(1, 'chrome', ['url', 'arg1'], expect.objectContaining({
env: expect.objectContaining({
env1: 'true',
env2: 'false',
env3: 'true',
}),
}))
// @ts-expect-error
expect(cp.spawn.mock.calls[0][2].env).not.toHaveProperty('ARCHPREFERENCE')
})
})
})
})
-175
View File
@@ -1,175 +0,0 @@
import _ from 'lodash'
import os from 'os'
import cp from 'child_process'
import * as darwinHelper from '../../lib/darwin'
import * as linuxHelper from '../../lib/linux'
import * as darwinUtil from '../../lib/darwin/util'
import { utils } from '../../lib/utils'
import { expect } from 'chai'
import sinon, { SinonStub } from 'sinon'
import { launch } from '../../lib/browsers'
import { knownBrowsers } from '../../lib/known-browsers'
import Bluebird from 'bluebird'
import fse from 'fs-extra'
import snapshot from 'snap-shot-it'
import { PassThrough } from 'stream'
import { FoundBrowser } from '@packages/types'
function generatePlist (key, value) {
return `
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>${key}</key>
<string>${value}</string>
</dict>
</plist>
`
}
function stubBrowser (findAppParams: darwinUtil.FindAppParams) {
(utils.getOutput as unknown as SinonStub)
.withArgs(`mdfind 'kMDItemCFBundleIdentifier=="${findAppParams.bundleId}"' | head -1`)
.resolves({ stdout: `/Applications/${findAppParams.appName}` })
;(fse.readFile as SinonStub)
.withArgs(`/Applications/${findAppParams.appName}/Contents/Info.plist`)
.resolves(generatePlist(findAppParams.versionProperty, 'someVersion'))
}
function spawnStub () {
const stub: any = {
on: sinon.stub(),
stdout: new PassThrough(),
stderr: new PassThrough(),
kill: sinon.stub(),
}
stub.once = stub.on
stub.on.withArgs('exit').callsArgAsync(1)
stub.on.withArgs('close').callsArgAsync(1)
stub.stderr.end()
stub.stdout.end()
return stub as cp.ChildProcess
}
describe('darwin browser detection', () => {
let getOutput: SinonStub
beforeEach(() => {
sinon.stub(fse, 'readFile').rejects({ code: 'ENOENT' })
getOutput = sinon.stub(utils, 'getOutput').resolves({ stdout: '' })
})
it('detects browsers as expected', async () => {
// this test uses the macOS detectors to stub out the expected calls
_.forEach(darwinHelper.browsers, (channels) => {
_.forEach(channels, stubBrowser)
})
// then, it uses the main browsers list to attempt detection of all browsers, which should succeed
const detected = (await Bluebird.mapSeries(knownBrowsers, (browser) => {
return darwinHelper.detect(browser)
.then((foundBrowser) => {
const findAppParams = darwinHelper.browsers[browser.name][browser.channel]
return _.merge(browser, foundBrowser, { findAppParams })
})
}))
snapshot(detected)
})
it('getVersionString is re-exported from linuxHelper', () => {
expect(darwinHelper.getVersionString).to.eq(linuxHelper.getVersionString)
})
context('forces correct architecture', () => {
function stubForArch (arch: 'arm64' | 'x64') {
sinon.stub(process, 'env').value({ env2: 'false', env3: 'true' })
sinon.stub(os, 'arch').returns(arch)
sinon.stub(os, 'platform').returns('darwin')
getOutput.restore()
return sinon.stub(cp, 'spawn').returns(spawnStub())
}
context('in version detection', () => {
it('uses arch and ARCHPREFERENCE on arm64', async () => {
const cpSpawn = stubForArch('arm64')
// this will error since we aren't setting stdout
await (darwinHelper.detect(knownBrowsers[0]).catch(() => {}))
// first call is mdfind, second call is getVersionString
const { args } = cpSpawn.getCall(1)
expect(args[0]).to.eq('arch')
expect(args[1]).to.deep.eq([knownBrowsers[0].binary, '--version'])
expect(args[2].env).to.deep.include({
ARCHPREFERENCE: 'arm64,x86_64',
env2: 'false',
env3: 'true',
})
})
it('does not use `arch` on x64', async () => {
const cpSpawn = stubForArch('x64')
// this will error since we aren't setting stdout
await (darwinHelper.detect(knownBrowsers[0]).catch(() => {}))
// first call is mdfind, second call is getVersionString
const { args } = cpSpawn.getCall(1)
expect(args[0]).to.eq(knownBrowsers[0].binary)
expect(args[1]).to.deep.eq(['--version'])
expect(args[2].env).to.deep.include({
env2: 'false',
env3: 'true',
})
})
})
context('in browser launching', () => {
it('uses arch and ARCHPREFERENCE on arm64', async () => {
const cpSpawn = stubForArch('arm64')
await launch({ path: 'chrome' } as unknown as FoundBrowser, 'url', 123, ['arg1'], { env1: 'true', env2: 'true' })
const { args } = cpSpawn.getCall(0)
expect(args[0]).to.eq('arch')
expect(args[1]).to.deep.eq(['chrome', 'url', 'arg1'])
expect(args[2].env).to.deep.include({
ARCHPREFERENCE: 'arm64,x86_64',
env1: 'true',
env2: 'false',
env3: 'true',
})
})
it('does not use `arch` on x64', async () => {
const cpSpawn = stubForArch('x64')
await launch({ path: 'chrome' } as unknown as FoundBrowser, 'url', 123, ['arg1'], { env1: 'true', env2: 'true' })
const { args } = cpSpawn.getCall(0)
expect(args[0]).to.eq('chrome')
expect(args[1]).to.deep.eq(['url', 'arg1'])
expect(args[2].env).to.deep.include({
env1: 'true',
env2: 'false',
env3: 'true',
})
expect(args[2].env).to.not.have.property('ARCHPREFERENCE')
})
})
})
})
+287
View File
@@ -0,0 +1,287 @@
import { describe, it, expect, beforeEach, vi } from 'vitest'
import _ from 'lodash'
import cp from 'child_process'
import { EventEmitter } from 'stream'
import { detect, detectByPath, getMajorVersion } from '../../lib/detect'
import { goalBrowsers } from '../fixtures'
import os from 'os'
import { log } from '../log'
import { detect as linuxDetect } from '../../lib/linux'
import { detect as darwinDetect } from '../../lib/darwin'
import { detect as windowsDetect } from '../../lib/windows'
import type { Browser } from '@packages/types'
vi.mock('child_process', async (importActual) => {
const actual = await importActual()
return {
default: {
// @ts-expect-error
...actual.default,
spawn: vi.fn(),
},
}
})
vi.mock('../../lib/linux', async (importActual) => {
const actual = await importActual()
return {
// @ts-expect-error
...actual,
detect: vi.fn(),
}
})
vi.mock('../../lib/darwin', async (importActual) => {
const actual = await importActual()
return {
// @ts-expect-error
...actual,
detect: vi.fn(),
}
})
vi.mock('../../lib/windows', async (importActual) => {
const actual = await importActual()
return {
// @ts-expect-error
...actual,
detect: vi.fn(),
}
})
const isWindows = () => {
return os.platform() === 'win32'
}
describe('detect', () => {
beforeEach(async () => {
vi.unstubAllEnvs()
vi.resetAllMocks()
const { detect: linuxDetectActual } = await vi.importActual<typeof import('../../lib/linux')>('../../lib/linux')
const { detect: darwinDetectActual } = await vi.importActual<typeof import('../../lib/darwin')>('../../lib/darwin')
const { detect: windowsDetectActual } = await vi.importActual<typeof import('../../lib/windows')>('../../lib/windows')
vi.mocked(linuxDetect).mockImplementation(linuxDetectActual)
vi.mocked(darwinDetect).mockImplementation(darwinDetectActual)
vi.mocked(windowsDetect).mockImplementation(windowsDetectActual)
const { spawn } = await vi.importActual<typeof import('child_process')>('child_process')
vi.mocked(cp.spawn).mockImplementation(spawn)
})
// making simple to debug tests
// using DEBUG=... flag
// we are only going to run tests on platforms with at least
// one browser. This test, is really E2E because it finds
// real browsers
it('detects available browsers', async () => {
const browsers = await detect()
log('detected browsers %j', browsers)
expect(browsers).toBeInstanceOf(Array)
const mainProps = browsers.map((val) => _.pick(val, ['name', 'version']))
log('%d browsers\n%j', browsers.length, mainProps)
if (isWindows()) {
// we might not find any browsers on Windows CI
expect(browsers.length).toBeGreaterThanOrEqual(0)
} else {
expect(browsers.length).toBeGreaterThan(0)
}
})
describe('#getMajorVersion', () => {
it('parses major version from provided string', () => {
expect(getMajorVersion('123.45.67')).toEqual('123')
expect(getMajorVersion('Browser 77.1.0')).toEqual('Browser 77')
expect(getMajorVersion('999')).toEqual('999')
})
})
describe('#detect', () => {
const testBrowser = {
name: 'test-browser',
family: 'chromium',
channel: 'test-channel',
displayName: 'Test Browser',
versionRegex: /Test Browser (\S+)/m,
binary: 'test-browser-beta',
}
it('validates browser with own validator property', async () => {
// @ts-expect-error
vi.mocked(linuxDetect).mockImplementation((browser) => {
return Promise.resolve({
name: browser.name,
path: '/path/to/test-browser',
version: '130',
})
})
vi.mocked(darwinDetect).mockImplementation((browser) => {
return Promise.resolve({
name: browser.name,
path: '/path/to/test-browser',
version: '130',
})
})
// @ts-expect-error
vi.mocked(windowsDetect).mockImplementation((browser) => {
return Promise.resolve({
name: browser.name,
path: '/path/to/test-browser',
version: '130',
})
})
const mockValidator = vi.fn().mockReturnValue({ isSupported: true })
const foundBrowsers = await detect([{ ...testBrowser as Browser, validator: mockValidator }])
expect(foundBrowsers).toHaveLength(1)
const foundTestBrowser = foundBrowsers[0]
expect(foundTestBrowser.name).toEqual('test-browser')
expect(foundTestBrowser.displayName).toEqual('Test Browser')
expect(foundTestBrowser.majorVersion, 'majorVersion').toEqual('130')
expect(foundTestBrowser.unsupportedVersion, 'unsupportedVersion').toBeUndefined()
expect(foundTestBrowser.warning, 'warning').toBeUndefined()
expect(mockValidator).toHaveBeenCalled()
})
})
describe('#detectByPath', () => {
let cpSpawnCallback: (cmd: string, args: readonly string[], opts, cp: cp.ChildProcess) => void
beforeEach(() => {
vi.unstubAllEnvs()
vi.resetAllMocks()
vi.mocked(cp.spawn).mockImplementation((cmd, args, opts) => {
const cpSpawnMock = {
on: vi.fn(),
stdout: new EventEmitter(),
stderr: new EventEmitter(),
kill: vi.fn(),
}
cpSpawnMock.on.mockImplementation((event: string, callback: (...args: any[]) => void) => {
if (event === 'exit') {
setTimeout(() => callback(), 0)
}
if (event === 'close') {
setTimeout(() => callback(), 0)
}
})
cpSpawnCallback(cmd, args, opts, cpSpawnMock as unknown as cp.ChildProcess)
return cpSpawnMock as unknown as cp.ChildProcess
})
cpSpawnCallback = (cmd, args, opts, cpSpawnMock) => {
// FIXME: these tests really should be reworked to run the same regardless of OS/CPU architecture
const command = os.arch() === 'arm64' ? args[0] : cmd
if (command === '/Applications/My Shiny New Browser.app') {
setTimeout(() => {
cpSpawnMock.stdout.emit('data', 'foo-browser v100.1.2.3')
}, 0)
return
}
if (command === '/foo/bar/browser') {
setTimeout(() => {
cpSpawnMock.stdout.emit('data', 'foo-browser v9001.1.2.3')
}, 0)
return
}
if (command === '/not/a/browser') {
setTimeout(() => {
cpSpawnMock.stdout.emit('data', 'not a browser version string')
}, 0)
return
}
if (command === '/not/a/real/path') {
setTimeout(() => {
cpSpawnMock.stdout.emit('data', '')
}, 0)
return
}
}
})
it('detects by path', async () => {
// @ts-expect-error
const foundBrowser = await detectByPath('/foo/bar/browser', goalBrowsers)
const expectedBrowser = goalBrowsers.find(({ name }) => name === 'foo-browser')
expect(foundBrowser).toEqual({
...expectedBrowser,
displayName: 'Custom Foo Browser',
info: 'Loaded from /foo/bar/browser',
custom: true,
version: '9001.1.2.3',
majorVersion: '9001',
path: '/foo/bar/browser',
})
})
it('rejects when there was no matching versionRegex', async () => {
try {
// @ts-expect-error
await detectByPath('/not/a/browser', goalBrowsers)
throw Error('Should not find a browser')
} catch (err) {
expect(err.notDetectedAtPath).toBe(true)
}
})
it('rejects when there was an error executing the command', async () => {
try {
// @ts-expect-error
await detectByPath('/not/a/real/path', goalBrowsers)
throw Error('Should not find a browser')
} catch (err) {
expect(err.notDetectedAtPath).toBe(true)
}
})
it('works with spaces in the path', async () => {
// @ts-expect-error
const foundBrowser = await detectByPath('/Applications/My Shiny New Browser.app', goalBrowsers)
const expectedBrowser = goalBrowsers.find(({ name }) => name === 'foo-browser')
expect(foundBrowser).toEqual({
...expectedBrowser,
displayName: 'Custom Foo Browser',
info: 'Loaded from /Applications/My Shiny New Browser.app',
custom: true,
version: '100.1.2.3',
majorVersion: '100',
path: '/Applications/My Shiny New Browser.app',
})
})
})
})
-174
View File
@@ -1,174 +0,0 @@
require('../spec_helper')
import _ from 'lodash'
import { detect, detectByPath, getMajorVersion } from '../../lib/detect'
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'
}
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) => {
log('detected browsers %j', browsers)
expect(browsers).to.be.an('array')
const mainProps = browsers.map((val) => _.pick(val, ['name', 'version']))
log('%d browsers\n%j', browsers.length, mainProps)
if (isWindows()) {
// we might not find any browsers on Windows CI
expect(browsers.length).to.be.gte(0)
} else {
expect(browsers.length).to.be.gt(0)
}
}
// we are only going to run tests on platforms with at least
// one browser. This test, is really E2E because it finds
// real browsers
it('detects available browsers', () => {
return detect().then(checkBrowsers)
})
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')
})
})
describe('#detect', () => {
const testBrowser = {
name: 'test-browser',
family: 'chromium',
channel: 'test-channel',
displayName: 'Test Browser',
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: '130',
})
})
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('130')
expect(foundTestBrowser.unsupportedVersion, 'unsupportedVersion').to.be.undefined
expect(foundTestBrowser.warning, 'warning').to.be.undefined
expect(mockValidator).to.have.been.called
})
})
describe('#detectByPath', () => {
let execa: SinonStub
beforeEach(() => {
execa = sinon.stub(utils, 'getOutput')
execa.withArgs('/Applications/My Shiny New Browser.app', ['--version'])
.resolves({ stdout: 'foo-browser v100.1.2.3' })
execa.withArgs('/foo/bar/browser', ['--version'])
.resolves({ stdout: 'foo-browser v9001.1.2.3' })
execa.withArgs('/not/a/browser', ['--version'])
.resolves({ stdout: 'not a browser version string' })
execa.withArgs('/not/a/real/path', ['--version'])
.rejects()
})
it('detects by path', () => {
// @ts-ignore
return detectByPath('/foo/bar/browser', goalBrowsers)
.then((browser) => {
expect(browser).to.deep.equal(
Object.assign({}, goalBrowsers.find((gb) => {
return gb.name === 'foo-browser'
}), {
displayName: 'Custom Foo Browser',
info: 'Loaded from /foo/bar/browser',
custom: true,
version: '9001.1.2.3',
majorVersion: '9001',
path: '/foo/bar/browser',
}),
)
})
})
it('rejects when there was no matching versionRegex', () => {
// @ts-ignore
return detectByPath('/not/a/browser', goalBrowsers)
.then(() => {
throw Error('Should not find a browser')
})
.catch((err) => {
expect(err.notDetectedAtPath).to.be.true
})
})
it('rejects when there was an error executing the command', () => {
// @ts-ignore
return detectByPath('/not/a/real/path', goalBrowsers)
.then(() => {
throw Error('Should not find a browser')
})
.catch((err) => {
expect(err.notDetectedAtPath).to.be.true
})
})
it('works with spaces in the path', () => {
// @ts-ignore
return detectByPath('/Applications/My Shiny New Browser.app', goalBrowsers)
.then((browser) => {
expect(browser).to.deep.equal(
Object.assign({}, goalBrowsers.find((gb) => {
return gb.name === 'foo-browser'
}), {
displayName: 'Custom Foo Browser',
info: 'Loaded from /Applications/My Shiny New Browser.app',
custom: true,
version: '100.1.2.3',
majorVersion: '100',
path: '/Applications/My Shiny New Browser.app',
}),
)
})
})
})
})
+320
View File
@@ -0,0 +1,320 @@
import { describe, it, expect, beforeEach, vi } from 'vitest'
import _ from 'lodash'
import cp from 'child_process'
import { EventEmitter } from 'events'
import * as linuxHelper from '../../lib/linux'
import { log } from '../log'
import { detect } from '../../lib/detect'
import { goalBrowsers } from '../fixtures'
import os from 'os'
import mockFs from 'mock-fs'
vi.mock('os', async (importActual) => {
const actual = await importActual()
return {
default: {
// @ts-expect-error
...actual.default,
platform: vi.fn(),
release: vi.fn(),
homedir: vi.fn(),
},
}
})
vi.mock('child_process', async (importActual) => {
const actual = await importActual()
return {
default: {
// @ts-expect-error
...actual.default,
spawn: vi.fn(),
},
}
})
describe('linux browser detection', () => {
let cpSpawnCallback: (cmd: string, args: readonly string[], opts, cp: cp.ChildProcess) => void
beforeEach(() => {
vi.unstubAllEnvs()
vi.resetAllMocks()
vi.mocked(os.platform).mockReturnValue('linux')
vi.mocked(os.release).mockReturnValue('1.0.0')
vi.mocked(cp.spawn).mockImplementation((cmd, args, opts) => {
const cpSpawnMock = {
on: vi.fn(),
stdout: new EventEmitter(),
stderr: new EventEmitter(),
kill: vi.fn(),
}
cpSpawnMock.on.mockImplementation((event: string, callback: (...args: any[]) => void) => {
if (event === 'exit') {
setTimeout(() => callback(), 0)
}
if (event === 'close') {
setTimeout(() => callback(), 0)
}
})
cpSpawnCallback(cmd, args, opts, cpSpawnMock as unknown as cp.ChildProcess)
return cpSpawnMock as unknown as cp.ChildProcess
})
})
afterEach(() => {
mockFs.restore()
})
it('detects browser by running --version', async () => {
const goal = goalBrowsers[0]
cpSpawnCallback = (cmd, args, opts, cpSpawnMock) => {
if (cmd === 'test-browser') {
setTimeout(() => {
cpSpawnMock.stdout.emit('data', 'test-browser v100.1.2.3')
}, 0)
}
}
// @ts-expect-error
const browser = await linuxHelper.detect(goal)
expect(browser).toEqual({
name: 'test-browser-name',
path: 'test-browser',
version: '100.1.2.3',
})
})
// https://github.com/cypress-io/cypress/pull/7039
it('sets profilePath on snapcraft chromium', async () => {
vi.mocked(os.homedir).mockReturnValue('/home/foo')
cpSpawnCallback = (cmd, args, opts, cpSpawnMock) => {
if (cmd === 'chromium') {
setTimeout(() => {
cpSpawnMock.stdout.emit('data', 'Chromium 64.2.3 snap')
}, 0)
}
}
const [browser] = await detect()
expect(browser).toEqual({
channel: 'stable',
name: 'chromium',
family: 'chromium',
displayName: 'Chromium',
majorVersion: '64',
path: 'chromium',
profilePath: '/home/foo/snap/chromium/current',
version: '64.2.3',
})
})
// https://github.com/cypress-io/cypress/issues/19793
describe('sets profilePath on snapcraft firefox', () => {
const expectedSnapFirefox = {
channel: 'stable',
name: 'firefox',
family: 'firefox',
displayName: 'Firefox',
majorVersion: '135',
path: 'firefox',
profilePath: '/home/foo/snap/firefox/current',
version: '135.0.1',
}
beforeEach(() => {
cpSpawnCallback = (cmd, args, opts, cpSpawnMock) => {
if (cmd === 'firefox') {
setTimeout(() => {
cpSpawnMock.stdout.emit('data', 'Mozilla Firefox 135.0.1')
}, 0)
}
}
vi.mocked(os.homedir).mockReturnValue('/home/foo')
})
it('with shim script', async () => {
vi.stubEnv('PATH', '/bin')
mockFs({
'/bin/firefox': mockFs.symlink({ path: '/usr/bin/firefox' }),
'/usr/bin/firefox': mockFs.file({ mode: 0o777, content: 'foo bar foo bar foo bar\nexec /snap/bin/firefox\n' }),
})
const [browser] = await detect()
expect(browser).toEqual(expectedSnapFirefox)
})
it('with /snap/bin in path', async () => {
vi.stubEnv('PATH', '/bin:/snap/bin')
mockFs({
'/snap/bin/firefox': mockFs.file({ mode: 0o777, content: 'binary' }),
})
const [browser] = await detect()
expect(browser).toEqual(expectedSnapFirefox)
})
it('with symlink to /snap/bin in path', async () => {
vi.stubEnv('PATH', '/bin')
mockFs({
'/bin/firefox': mockFs.symlink({ path: '/snap/bin/firefox' }),
'/snap/bin/firefox': mockFs.file({ mode: 0o777, content: 'binary' }),
})
const [browser] = await detect()
expect(browser).toEqual(expectedSnapFirefox)
})
})
// https://github.com/cypress-io/cypress/issues/6669
it('detects browser if the --version stdout is multiline', async () => {
cpSpawnCallback = (cmd, args, opts, cpSpawnMock) => {
if (cmd === 'multiline-foo') {
setTimeout(() => {
cpSpawnMock.stdout.emit('data', `
Running without a11y support!
foo-browser v9001.1.2.3
`)
}, 0)
}
}
const goal = _.defaults({ binary: 'multiline-foo' }, _.find(goalBrowsers, { name: 'foo-browser' }))
// @ts-expect-error
const [browser] = await detect([goal])
expect(browser).toEqual({
displayName: 'Foo Browser',
majorVersion: '9001',
name: 'foo-browser',
path: 'multiline-foo',
version: '9001.1.2.3',
})
})
// despite using detect(), this test is in linux/spec instead of detect_spec because it is
// testing side effects that occur within the Linux-specific detect function
// https://github.com/cypress-io/cypress/issues/1400
it('properly eliminates duplicates', async () => {
const expected = [
{
displayName: 'Test Browser',
name: 'test-browser-name',
version: '100.1.2.3',
path: 'test-browser',
majorVersion: '100',
},
{
displayName: 'Foo Browser',
name: 'foo-browser',
version: '100.1.2.3',
path: 'foo-browser',
majorVersion: '100',
},
]
cpSpawnCallback = (cmd, args, opts, cpSpawnMock) => {
if (cmd === 'test-browser') {
setTimeout(() => {
cpSpawnMock.stdout.emit('data', 'test-browser v100.1.2.3')
}, 0)
}
if (cmd === 'foo-browser') {
setTimeout(() => {
cpSpawnMock.stdout.emit('data', 'foo-browser v100.1.2.3')
}, 0)
}
}
// @ts-expect-error
const browsers = await detect(goalBrowsers)
log('Browsers: %o', browsers)
log('Expected browsers: %o', expected)
expect(browsers).toEqual(expected)
})
it('considers multiple binary names', async () => {
const goalBrowsers = [
{
name: 'foo-browser',
versionRegex: /v(\S+)$/,
binary: ['foo-browser', 'foo-bar-browser'],
},
]
const expected = [
{
name: 'foo-browser',
version: '100.1.2.3',
path: 'foo-browser',
majorVersion: '100',
},
]
cpSpawnCallback = (cmd, args, opts, cpSpawnMock) => {
if (cmd === 'foo-browser' || cmd === 'foo-bar-browser') {
setTimeout(() => {
cpSpawnMock.stdout.emit('data', 'foo-browser v100.1.2.3')
}, 0)
}
}
//@ts-expect-error
const browsers = await detect(goalBrowsers)
log('Browsers: %o', browsers)
log('Expected browsers: %o', expected)
expect(browsers).toEqual(expected)
})
describe('#getVersionString', () => {
it('runs the command with `--version` and returns trimmed output', async () => {
cpSpawnCallback = (cmd, args, opts, cpSpawnMock) => {
if (cmd === 'foo') {
setTimeout(() => {
cpSpawnMock.stdout.emit('data', ' bar ')
}, 0)
}
}
const versionString = await linuxHelper.getVersionString('foo')
expect(versionString).toEqual('bar')
})
it('rejects with errors', async () => {
const err = new Error()
cpSpawnCallback = (cmd, args, opts, cpSpawnMock) => {
if (cmd === 'foo') {
// @ts-expect-error - overriding the mock on this method
cpSpawnMock.on.mockImplementation((event: string, callback: (...args: any[]) => void) => {
if (event === 'error') {
setTimeout(() => callback(err), 0)
}
})
}
}
await expect(linuxHelper.getVersionString('foo')).rejects.toThrow(err)
})
})
})
-230
View File
@@ -1,230 +0,0 @@
require('../spec_helper')
import _ from 'lodash'
import * as linuxHelper from '../../lib/linux'
import 'chai-as-promised'
import { log } from '../log'
import { detect } from '../../lib/detect'
import { goalBrowsers } from '../fixtures'
import { expect } from 'chai'
import { utils } from '../../lib/utils'
import os from 'os'
import sinon, { SinonStub } from 'sinon'
import mockFs from 'mock-fs'
describe('linux browser detection', () => {
let execa: SinonStub
let cachedEnv = { ...process.env }
beforeEach(() => {
execa = sinon.stub(utils, 'getOutput')
sinon.stub(os, 'platform').returns('linux')
sinon.stub(os, 'release').returns('1.0.0')
execa.withArgs('test-browser', ['--version'])
.resolves({ stdout: 'test-browser v100.1.2.3' })
execa.withArgs('foo-browser', ['--version'])
.resolves({ stdout: 'foo-browser v100.1.2.3' })
execa.withArgs('foo-bar-browser', ['--version'])
.resolves({ stdout: 'foo-browser v100.1.2.3' })
execa.withArgs('/foo/bar/browser', ['--version'])
.resolves({ stdout: 'foo-browser v9001.1.2.3' })
})
afterEach(() => {
Object.assign(process.env, cachedEnv)
mockFs.restore()
sinon.restore()
})
it('detects browser by running --version', () => {
const goal = goalBrowsers[0]
const checkBrowser = (browser) => {
expect(browser).to.deep.equal({
name: 'test-browser-name',
path: 'test-browser',
version: '100.1.2.3',
})
}
// @ts-ignore
return linuxHelper.detect(goal).then(checkBrowser)
})
// https://github.com/cypress-io/cypress/pull/7039
it('sets profilePath on snapcraft chromium', () => {
execa.withArgs('chromium', ['--version'])
.resolves({ stdout: 'Chromium 64.2.3 snap' })
sinon.stub(os, 'homedir').returns('/home/foo')
const checkBrowser = ([browser]) => {
expect(browser).to.deep.equal({
channel: 'stable',
name: 'chromium',
family: 'chromium',
displayName: 'Chromium',
majorVersion: '64',
path: 'chromium',
profilePath: '/home/foo/snap/chromium/current',
version: '64.2.3',
})
}
return detect().then(checkBrowser)
})
// https://github.com/cypress-io/cypress/issues/19793
context('sets profilePath on snapcraft firefox', () => {
const expectedSnapFirefox = {
channel: 'stable',
name: 'firefox',
family: 'firefox',
displayName: 'Firefox',
majorVersion: '135',
path: 'firefox',
profilePath: '/home/foo/snap/firefox/current',
version: '135.0.1',
}
beforeEach(() => {
execa.withArgs('firefox', ['--version'])
.resolves({ stdout: 'Mozilla Firefox 135.0.1' })
sinon.stub(os, 'homedir').returns('/home/foo')
})
it('with shim script', async () => {
process.env.PATH = '/bin'
mockFs({
'/bin/firefox': mockFs.symlink({ path: '/usr/bin/firefox' }),
'/usr/bin/firefox': mockFs.file({ mode: 0o777, content: 'foo bar foo bar foo bar\nexec /snap/bin/firefox\n' }),
})
const [browser] = await detect()
expect(browser).to.deep.equal(expectedSnapFirefox)
})
it('with /snap/bin in path', async () => {
process.env.PATH = '/bin:/snap/bin'
mockFs({
'/snap/bin/firefox': mockFs.file({ mode: 0o777, content: 'binary' }),
})
const [browser] = await detect()
expect(browser).to.deep.equal(expectedSnapFirefox)
})
it('with symlink to /snap/bin in path', async () => {
process.env.PATH = '/bin'
mockFs({
'/bin/firefox': mockFs.symlink({ path: '/snap/bin/firefox' }),
'/snap/bin/firefox': mockFs.file({ mode: 0o777, content: 'binary' }),
})
const [browser] = await detect()
expect(browser).to.deep.equal(expectedSnapFirefox)
})
})
// https://github.com/cypress-io/cypress/issues/6669
it('detects browser if the --version stdout is multiline', () => {
execa.withArgs('multiline-foo', ['--version'])
.resolves({
stdout: `
Running without a11y support!
foo-browser v9001.1.2.3
`,
})
const goal = _.defaults({ binary: 'multiline-foo' }, _.find(goalBrowsers, { name: 'foo-browser' }))
const checkBrowser = (browser) => {
expect(browser).to.deep.equal({
name: 'foo-browser',
path: 'multiline-foo',
version: '9001.1.2.3',
})
}
// @ts-ignore
return linuxHelper.detect(goal).then(checkBrowser)
})
// despite using detect(), this test is in linux/spec instead of detect_spec because it is
// testing side effects that occur within the Linux-specific detect function
// https://github.com/cypress-io/cypress/issues/1400
it('properly eliminates duplicates', () => {
const expected = [
{
displayName: 'Test Browser',
name: 'test-browser-name',
version: '100.1.2.3',
path: 'test-browser',
majorVersion: '100',
},
{
displayName: 'Foo Browser',
name: 'foo-browser',
version: '100.1.2.3',
path: 'foo-browser',
majorVersion: '100',
},
]
// @ts-ignore
return detect(goalBrowsers).then((browsers) => {
log('Browsers: %o', browsers)
log('Expected browsers: %o', expected)
expect(browsers).to.deep.equal(expected)
})
})
it('considers multiple binary names', () => {
const goalBrowsers = [
{
name: 'foo-browser',
versionRegex: /v(\S+)$/,
binary: ['foo-browser', 'foo-bar-browser'],
},
]
const expected = [
{
name: 'foo-browser',
version: '100.1.2.3',
path: 'foo-browser',
majorVersion: '100',
},
]
// @ts-ignore
return detect(goalBrowsers).then((browsers) => {
log('Browsers: %o', browsers)
log('Expected browsers: %o', expected)
expect(browsers).to.deep.equal(expected)
})
})
context('#getVersionString', () => {
it('runs the command with `--version` and returns trimmed output', async () => {
execa.withArgs('foo', ['--version']).resolves({ stdout: ' bar ' })
expect(await linuxHelper.getVersionString('foo')).to.eq('bar')
})
it('rejects with errors', async () => {
const err = new Error()
execa.withArgs('foo', ['--version']).rejects(err)
await expect(linuxHelper.getVersionString('foo')).to.be.rejectedWith(err)
})
})
})
+525
View File
@@ -0,0 +1,525 @@
import { describe, it, expect, beforeEach, vi } from 'vitest'
import winVersionInfo from 'win-version-info'
import _ from 'lodash'
import * as windowsHelper from '../../lib/windows'
import { knownBrowsers } from '../../lib/known-browsers'
import fs from 'fs-extra'
import os from 'os'
import type { Browser } from '@packages/types'
import { detectByPath } from '../../lib/detect'
import { goalBrowsers } from '../fixtures'
vi.mock('os', async (importActual) => {
const actual = await importActual()
return {
default: {
// @ts-expect-error
...actual.default,
homedir: vi.fn(),
platform: vi.fn(),
},
}
})
vi.mock('fs-extra', async (importActual) => {
const actual = await importActual()
return {
default: {
// @ts-expect-error
...actual.default,
pathExists: vi.fn(),
},
}
})
vi.mock('win-version-info', () => {
return {
default: vi.fn(),
}
})
describe('windows browser detection', () => {
const HOMEDIR = 'C:/Users/flotwig'
let mockBrowsers: { path: string, version: string }[] = []
beforeEach(() => {
vi.resetAllMocks()
mockBrowsers = [
// chrome
{
path: 'C:/Program Files (x86)/Google/Chrome/Application/chrome.exe',
version: '1.2.3',
},
// chromium - 32-bit will be preferred for passivity
{
path: 'C:/Program Files (x86)/Google/chrome-win32/chrome.exe',
version: '2.3.4',
},
{
path: 'C:/Program Files/Google/chrome-win/chrome.exe',
version: '2.3.4',
},
// chrome-for-testing - 64-bit will be preferred
{
path: 'C:/Program Files (x86)/Google/Chrome for Testing/chrome.exe',
version: '1.2.3',
},
{
path: 'C:/Program Files/Google/Chrome for Testing/chrome.exe',
version: '1.2.3',
},
// chrome beta
{
path: 'C:/Program Files (x86)/Google/Chrome Beta/Application/chrome.exe',
version: '6.7.8',
},
// chrome canary is installed in homedir
{
path: `${HOMEDIR}/AppData/Local/Google/Chrome SxS/Application/chrome.exe`,
version: '3.4.5',
},
// have 32-bit and 64-bit ff - 64-bit will be preferred
{
path: 'C:/Program Files (x86)/Mozilla Firefox/firefox.exe',
version: '72',
},
{
path: 'C:/Program Files/Mozilla Firefox/firefox.exe',
version: '72',
},
// 32-bit dev edition
{
path: 'C:/Program Files (x86)/Firefox Developer Edition/firefox.exe',
version: '73',
},
// 64-bit nightly edition
{
path: 'C:/Program Files/Firefox Nightly/firefox.exe',
version: '74',
},
{
path: 'C:/Program Files (x86)/Microsoft/Edge/Application/msedge.exe',
version: '11',
},
{
path: 'C:/Program Files (x86)/Microsoft/Edge Beta/Application/msedge.exe',
version: '12',
},
{
path: 'C:/Program Files (x86)/Microsoft/Edge Dev/Application/msedge.exe',
version: '13',
},
{
// edge canary is installed in homedir
path: `${HOMEDIR}/AppData/Local/Microsoft/Edge SxS/Application/msedge.exe`,
version: '14',
},
]
vi.mocked(os.homedir).mockReturnValue(HOMEDIR)
vi.mocked(os.platform).mockReturnValue('win32')
vi.mocked(fs.pathExists).mockImplementation((path) => {
const browser = mockBrowsers.find((browser) => windowsHelper.doubleEscape(browser.path) === path)
if (!browser) {
return Promise.resolve(false)
}
return Promise.resolve(true)
})
vi.mocked(winVersionInfo).mockImplementation((path) => {
const browser = mockBrowsers.find((browser) => windowsHelper.doubleEscape(browser.path) === path)
if (!browser) {
throw new Error('Browser not found')
}
return { FileVersion: browser?.version }
})
})
it('detects browsers as expected', async () => {
const mappedBrowsers = []
for (const browser of knownBrowsers) {
const foundBrowser = await windowsHelper.detect(browser)
mappedBrowsers.push({
...browser,
...foundBrowser,
})
}
expect(mappedBrowsers).toMatchSnapshot()
})
it('detects Chrome Beta 64-bit install', async () => {
// mock installing the 64-bit (32-bit installed already in mockBrowsers)
// should prefer the 64-bit install over the 32-bit install
mockBrowsers.push({
path: 'C:/Program Files/Google/Chrome Beta/Application/chrome.exe',
version: '9.0.1',
})
const chrome = _.find(knownBrowsers, { name: 'chrome', channel: 'beta' })! as Browser
const foundBrowser = await windowsHelper.detect(chrome)
const snapshotBrowser = {
...chrome,
...foundBrowser,
}
expect(snapshotBrowser.version).toEqual('9.0.1')
expect(snapshotBrowser).toMatchSnapshot()
})
// @see https://github.com/cypress-io/cypress/issues/8425
it('detects Chrome 64-bit install', async () => {
// mock installing the 64-bit (32-bit installed already in mockBrowsers)
// should prefer the 64-bit install over the 32-bit install
mockBrowsers.push({
path: 'C:/Program Files/Google/Chrome/Application/chrome.exe',
version: '4.4.4',
})
const chrome = _.find(knownBrowsers, { name: 'chrome', channel: 'stable' })! as Browser
const foundBrowser = await windowsHelper.detect(chrome)
const snapshotBrowser = {
...chrome,
...foundBrowser,
}
expect(snapshotBrowser.version).toEqual('4.4.4')
expect(snapshotBrowser).toMatchSnapshot()
})
it('detects Chrome for Testing 32-bit install', async () => {
// mock uninstalling the 32-bit and 64-bit
const foundCFTInstalls = _.remove(mockBrowsers, (browser) => browser.path.includes('Chrome for Testing'))
expect(foundCFTInstalls).toHaveLength(2)
// mock installing the 32-bit
mockBrowsers.push({
path: 'C:/Program Files (x86)/Google/Chrome for Testing/chrome.exe',
version: '5.5.5',
})
const chromeForTesting = _.find(knownBrowsers, { name: 'chrome-for-testing' })!
const foundBrowser = await windowsHelper.detect(chromeForTesting)
const snapshotBrowser = {
...chromeForTesting,
...foundBrowser,
}
expect(snapshotBrowser.version).toEqual('5.5.5')
expect(snapshotBrowser).toMatchSnapshot()
})
// @see https://github.com/cypress-io/cypress/issues/8432
it('detects Firefox local installs', async () => {
// mock uninstalling Firefox in the Program Files directory
const foundFirefoxInstalls = _.remove(mockBrowsers, (browser) => browser.path.includes('Firefox'))
expect(foundFirefoxInstalls).toHaveLength(4)
// mock installing Firefox in the local app data directory
mockBrowsers.push({
path: `${HOMEDIR}/AppData/Local/Mozilla Firefox/firefox.exe`,
version: '100',
})
mockBrowsers.push({
path: `${HOMEDIR}/AppData/Local/Firefox Nightly/firefox.exe`,
version: '200',
})
mockBrowsers.push({
path: `${HOMEDIR}/AppData/Local/Firefox Developer Edition/firefox.exe`,
version: '300',
})
const firefoxBrowsers = _.filter(knownBrowsers, { family: 'firefox' })
const mappedBrowsers = []
for (const browser of firefoxBrowsers) {
const foundBrowser = await windowsHelper.detect(browser)
mappedBrowsers.push({
...browser,
...foundBrowser,
})
}
expect(mappedBrowsers.map((browser) => browser.version).sort()).toEqual(['100', '200', '300'])
expect(mappedBrowsers).toMatchSnapshot()
})
it('detects Chromium 64-bit install', async () => {
// mock updating the 64-bit install of chrome
const foundChromiumInstalls = _.remove(mockBrowsers, (browser) => browser.path === 'C:/Program Files/Google/chrome-win/chrome.exe')
expect(foundChromiumInstalls).toHaveLength(1)
mockBrowsers.push({
path: 'C:/Program Files/Google/chrome-win/chrome.exe',
version: '6.6.6',
})
const chromium = _.find(knownBrowsers, { name: 'chromium' })!
const foundBrowser = await windowsHelper.detect(chromium)
const snapshotBrowser = {
...chromium,
...foundBrowser,
}
expect(snapshotBrowser.version).toEqual('6.6.6')
expect(snapshotBrowser).toMatchSnapshot()
})
it('detects Chromium 32-bit install in Chromium folder', async () => {
// mock uninstalling the 64-bit and 32-bit in the Google path
const foundChromiumInstalls = _.remove(mockBrowsers, (browser) => browser.path.includes('chrome-win'))
expect(foundChromiumInstalls).toHaveLength(2)
// mock installing the 32-bit
mockBrowsers.push({
path: 'C:/Program Files (x86)/Google/Chromium/chrome.exe',
version: '7.7.7',
})
const chromium = _.find(knownBrowsers, { name: 'chromium' })!
const foundBrowser = await windowsHelper.detect(chromium)
const snapshotBrowser = {
...chromium,
...foundBrowser,
}
expect(snapshotBrowser.version).toEqual('7.7.7')
expect(snapshotBrowser).toMatchSnapshot()
})
it('detects Chromium 64-bit install in Chromium folder', async () => {
// mock uninstalling the 64-bit and 32-bit in the Google path
const foundChromiumInstalls = _.remove(mockBrowsers, (browser) => browser.path.includes('chrome-win'))
expect(foundChromiumInstalls).toHaveLength(2)
// mock installing the 32-bit
mockBrowsers.push({
path: 'C:/Program Files/Google/Chromium/chrome.exe',
version: '8.8.8',
})
const chromium = _.find(knownBrowsers, { name: 'chromium' })!
const foundBrowser = await windowsHelper.detect(chromium)
const snapshotBrowser = {
...chromium,
...foundBrowser,
}
expect(snapshotBrowser.version).toEqual('8.8.8')
expect(snapshotBrowser).toMatchSnapshot()
})
it('works with :browserName format in Windows', async () => {
let path = `${HOMEDIR}/foo/bar/browser.exe`
let win10Path = windowsHelper.doubleEscape(path)
mockBrowsers.push({
path,
version: '100',
})
const foundBrowser = await detectByPath(`${path}:foo-browser`, goalBrowsers as Browser[])
const fooBrowser = goalBrowsers.find(({ name }) => name === 'foo-browser')!
expect(foundBrowser).toEqual(
{
...fooBrowser,
displayName: 'Custom Foo Browser',
info: `Loaded from ${win10Path}`,
custom: true,
version: '100',
majorVersion: '100',
path: win10Path,
},
)
})
it('identifies browser if name in path', async () => {
let path = `${HOMEDIR}/foo/bar/chrome.exe`
let win10Path = windowsHelper.doubleEscape(path)
mockBrowsers.push({
path,
version: '100',
})
const foundBrowser = await detectByPath(path)
const chromeBrowser = knownBrowsers.find(({ name }) => name === 'chrome')!
expect(foundBrowser).toEqual(
{
...chromeBrowser,
displayName: 'Custom Chrome',
info: `Loaded from ${win10Path}`,
custom: true,
version: '100',
majorVersion: '100',
path: win10Path,
},
)
})
describe('#getVersionString', () => {
it('returns the FileVersion from win-version-info', async () => {
mockBrowsers.push({
path: 'foo',
version: 'bar',
})
const versionString = await windowsHelper.getVersionString('foo')
expect(versionString).toEqual('bar')
})
})
describe('#getPathData', () => {
it('returns path and browserKey given path with browser key', () => {
const browserPath = 'C:\\foo\\bar.exe'
const res = windowsHelper.getPathData(`${browserPath}:firefox`)
expect(res.path).toEqual(windowsHelper.doubleEscape(browserPath))
expect(res.browserKey).toEqual('firefox')
})
it('returns path and browserKey given path with a lot of slashes plus browser key', () => {
const browserPath = 'C:\\\\\\\\foo\\\\\\bar.exe'
const res = windowsHelper.getPathData(`${browserPath}:firefox`)
expect(res.path).toEqual(windowsHelper.doubleEscape(browserPath))
expect(res.browserKey).toEqual('firefox')
})
it('returns path and browserKey given nix path with browser key', () => {
const browserPath = 'C:/foo/bar.exe'
const res = windowsHelper.getPathData(`${browserPath}:firefox`)
expect(res.path).toEqual(windowsHelper.doubleEscape(browserPath))
expect(res.browserKey).toEqual('firefox')
})
it('returns path and chrome given just path', () => {
const browserPath = 'C:\\foo\\bar\\chrome.exe'
const res = windowsHelper.getPathData(browserPath)
expect(res.path).toEqual(windowsHelper.doubleEscape(browserPath))
expect(res.browserKey).toEqual('chrome')
})
it('returns path and chrome given just nix path', () => {
const browserPath = 'C:/foo/bar/chrome.exe'
const res = windowsHelper.getPathData(browserPath)
expect(res.path).toEqual(windowsHelper.doubleEscape(browserPath))
expect(res.browserKey).toEqual('chrome')
})
it('returns path and edge given just path for edge', () => {
const browserPath = 'C:\\foo\\bar\\edge.exe'
const res = windowsHelper.getPathData(browserPath)
expect(res.path).toEqual(windowsHelper.doubleEscape(browserPath))
expect(res.browserKey).toEqual('edge')
})
it('returns path and edge given just path for msedge', () => {
const browserPath = 'C:\\foo\\bar\\msedge.exe'
const res = windowsHelper.getPathData(browserPath)
expect(res.path).toEqual(windowsHelper.doubleEscape(browserPath))
expect(res.browserKey).toEqual('edge')
})
it('returns path and edge given just nix path', () => {
const browserPath = 'C:/foo/bar/edge.exe'
const res = windowsHelper.getPathData(browserPath)
expect(res.path).toEqual(windowsHelper.doubleEscape(browserPath))
expect(res.browserKey).toEqual('edge')
})
it('returns path and edge given just nix path for msedge', () => {
const browserPath = 'C:/foo/bar/msedge.exe'
const res = windowsHelper.getPathData(browserPath)
expect(res.path).toEqual(windowsHelper.doubleEscape(browserPath))
expect(res.browserKey).toEqual('edge')
})
it('returns path and firefox given just path', () => {
const browserPath = 'C:\\foo\\bar\\firefox.exe'
const res = windowsHelper.getPathData(browserPath)
expect(res.path).toEqual(windowsHelper.doubleEscape(browserPath))
expect(res.browserKey).toEqual('firefox')
})
it('returns path and firefox given just nix path', () => {
const browserPath = 'C:/foo/bar/firefox.exe'
const res = windowsHelper.getPathData(browserPath)
expect(res.path).toEqual(windowsHelper.doubleEscape(browserPath))
expect(res.browserKey).toEqual('firefox')
})
})
describe('#doubleEscape', () => {
let winPath = 'C:\\\\foo\\\\bar.exe'
it('converts nix path into double escaped win path', async () => {
let nixPath = 'C:/foo/bar.exe'
expect(windowsHelper.doubleEscape(nixPath)).toEqual(winPath)
})
it('converts win path with different backslash combination into double escaped win path', async () => {
let badWinPath = 'C:\\\\\\\\\\foo\\bar.exe'
expect(windowsHelper.doubleEscape(badWinPath)).toEqual(winPath)
})
it('converts single escaped win path into double escaped win path', async () => {
let badWinPath = 'C:\\foo\\bar.exe'
expect(windowsHelper.doubleEscape(badWinPath)).toEqual(winPath)
})
it('does not affect an already double escaped win path', async () => {
let badWinPath = 'C:\\\\foo\\\\bar.exe'
expect(windowsHelper.doubleEscape(badWinPath)).toEqual(badWinPath)
})
})
})
-307
View File
@@ -1,307 +0,0 @@
import _ from 'lodash'
import { expect } from 'chai'
import * as windowsHelper from '../../lib/windows'
import { normalize } from 'path'
import sinon, { SinonStub } from 'sinon'
import { knownBrowsers } from '../../lib/known-browsers'
import Bluebird from 'bluebird'
import fse from 'fs-extra'
import os from 'os'
import snapshot from 'snap-shot-it'
import type { Browser } from '@packages/types'
import { detectByPath } from '../../lib/detect'
import { goalBrowsers } from '../fixtures'
function stubBrowser (path: string, version: string) {
path = windowsHelper.doubleEscape(normalize(path))
;(windowsHelper.getVersionString as unknown as SinonStub)
.withArgs(path)
.resolves(version)
;(fse.pathExists as SinonStub)
.withArgs(path)
.resolves(true)
}
function detect (goalBrowsers: Browser[]) {
return Bluebird.mapSeries(goalBrowsers, (browser) => {
return windowsHelper.detect(browser)
.then((foundBrowser) => {
return _.merge(browser, foundBrowser)
})
})
}
const HOMEDIR = 'C:/Users/flotwig'
describe('windows browser detection', () => {
beforeEach(() => {
sinon.stub(fse, 'pathExists').resolves(false)
sinon.stub(os, 'homedir').returns(HOMEDIR)
sinon.stub(windowsHelper, 'getVersionString').rejects()
})
it('detects browsers as expected', async () => {
// chrome
stubBrowser('C:/Program Files (x86)/Google/Chrome/Application/chrome.exe', '1.2.3')
// chromium - 32-bit will be preferred for passivity
stubBrowser('C:/Program Files (x86)/Google/chrome-win32/chrome.exe', '2.3.4')
stubBrowser('C:/Program Files/Google/chrome-win/chrome.exe', '2.3.4')
// chrome-for-testing - 64-bit will be preferred
stubBrowser('C:/Program Files (x86)/Google/Chrome for Testing/chrome.exe', '1.2.3')
stubBrowser('C:/Program Files/Google/Chrome for Testing/chrome.exe', '1.2.3')
// chrome beta
stubBrowser('C:/Program Files (x86)/Google/Chrome Beta/Application/chrome.exe', '6.7.8')
// chrome canary is installed in homedir
stubBrowser(`${HOMEDIR}/AppData/Local/Google/Chrome SxS/Application/chrome.exe`, '3.4.5')
// have 32-bit and 64-bit ff - 64-bit will be preferred
stubBrowser('C:/Program Files (x86)/Mozilla Firefox/firefox.exe', '72')
stubBrowser('C:/Program Files/Mozilla Firefox/firefox.exe', '72')
// 32-bit dev edition
stubBrowser('C:/Program Files (x86)/Firefox Developer Edition/firefox.exe', '73')
// 64-bit nightly edition
stubBrowser('C:/Program Files/Firefox Nightly/firefox.exe', '74')
stubBrowser('C:/Program Files (x86)/Microsoft/Edge/Application/msedge.exe', '11')
stubBrowser('C:/Program Files (x86)/Microsoft/Edge Beta/Application/msedge.exe', '12')
stubBrowser('C:/Program Files (x86)/Microsoft/Edge Dev/Application/msedge.exe', '13')
// edge canary is installed in homedir
stubBrowser(`${HOMEDIR}/AppData/Local/Microsoft/Edge SxS/Application/msedge.exe`, '14')
snapshot(await detect(knownBrowsers))
})
it('detects Chrome Beta 64-bit install', async () => {
stubBrowser('C:/Program Files/Google/Chrome Beta/Application/chrome.exe', '9.0.1')
const chrome = _.find(knownBrowsers, { name: 'chrome', channel: 'beta' })!
snapshot(await detect([chrome]))
})
// @see https://github.com/cypress-io/cypress/issues/8425
it('detects Chrome 64-bit install', async () => {
stubBrowser('C:/Program Files/Google/Chrome/Application/chrome.exe', '4.4.4')
const chrome = _.find(knownBrowsers, { name: 'chrome', channel: 'stable' })!
snapshot(await detect([chrome]))
})
it('detects Chrome for Testing 32-bit install', async () => {
stubBrowser('C:/Program Files (x86)/Google/Chrome for Testing/chrome.exe', '5.5.5')
const chromeForTesting = _.find(knownBrowsers, { name: 'chrome-for-testing' })!
snapshot(await detect([chromeForTesting]))
})
// @see https://github.com/cypress-io/cypress/issues/8432
it('detects Firefox local installs', async () => {
stubBrowser(`${HOMEDIR}/AppData/Local/Mozilla Firefox/firefox.exe`, '100')
stubBrowser(`${HOMEDIR}/AppData/Local/Firefox Nightly/firefox.exe`, '200')
stubBrowser(`${HOMEDIR}/AppData/Local/Firefox Developer Edition/firefox.exe`, '300')
const firefoxes = _.filter(knownBrowsers, { family: 'firefox' })
snapshot(await detect(firefoxes))
})
it('detects Chromium 64-bit install', async () => {
stubBrowser('C:/Program Files/Google/chrome-win/chrome.exe', '6.6.6')
const chromium = _.find(knownBrowsers, { name: 'chromium' })!
snapshot(await detect([chromium]))
})
it('detects Chromium 32-bit install in Chromium folder', async () => {
stubBrowser('C:/Program Files (x86)/Google/Chromium/chrome.exe', '7.7.7')
const chromium = _.find(knownBrowsers, { name: 'chromium' })!
snapshot(await detect([chromium]))
})
it('detects Chromium 64-bit install in Chromium folder', async () => {
stubBrowser('C:/Program Files/Google/Chromium/chrome.exe', '8.8.8')
const chromium = _.find(knownBrowsers, { name: 'chromium' })!
snapshot(await detect([chromium]))
})
it('works with :browserName format in Windows', () => {
sinon.stub(os, 'platform').returns('win32')
let path = `${HOMEDIR}/foo/bar/browser.exe`
let win10Path = windowsHelper.doubleEscape(path)
stubBrowser(path, '100')
return detectByPath(`${path}:foo-browser`, goalBrowsers as Browser[]).then((browser) => {
expect(browser).to.deep.equal(
Object.assign({}, goalBrowsers.find((gb) => {
return gb.name === 'foo-browser'
}), {
displayName: 'Custom Foo Browser',
info: `Loaded from ${win10Path}`,
custom: true,
version: '100',
majorVersion: '100',
path: win10Path,
}),
)
})
})
it('identifies browser if name in path', async () => {
sinon.stub(os, 'platform').returns('win32')
let path = `${HOMEDIR}/foo/bar/chrome.exe`
let win10Path = windowsHelper.doubleEscape(path)
stubBrowser(path, '100')
return detectByPath(path).then((browser) => {
expect(browser).to.deep.equal(
Object.assign({}, knownBrowsers.find((gb) => {
return gb.name === 'chrome'
}), {
displayName: 'Custom Chrome',
info: `Loaded from ${win10Path}`,
custom: true,
version: '100',
majorVersion: '100',
path: win10Path,
}),
)
})
})
context('#getVersionString', () => {
it('returns the FileVersion from win-version-info', async () => {
stubBrowser('foo', 'bar')
expect(await windowsHelper.getVersionString('foo')).to.eq('bar')
})
})
context('#getPathData', () => {
it('returns path and browserKey given path with browser key', () => {
const browserPath = 'C:\\foo\\bar.exe'
const res = windowsHelper.getPathData(`${browserPath}:firefox`)
expect(res.path).to.eq(windowsHelper.doubleEscape(browserPath))
expect(res.browserKey).to.eq('firefox')
})
it('returns path and browserKey given path with a lot of slashes plus browser key', () => {
const browserPath = 'C:\\\\\\\\foo\\\\\\bar.exe'
const res = windowsHelper.getPathData(`${browserPath}:firefox`)
expect(res.path).to.eq(windowsHelper.doubleEscape(browserPath))
expect(res.browserKey).to.eq('firefox')
})
it('returns path and browserKey given nix path with browser key', () => {
const browserPath = 'C:/foo/bar.exe'
const res = windowsHelper.getPathData(`${browserPath}:firefox`)
expect(res.path).to.eq(windowsHelper.doubleEscape(browserPath))
expect(res.browserKey).to.eq('firefox')
})
it('returns path and chrome given just path', () => {
const browserPath = 'C:\\foo\\bar\\chrome.exe'
const res = windowsHelper.getPathData(browserPath)
expect(res.path).to.eq(windowsHelper.doubleEscape(browserPath))
expect(res.browserKey).to.eq('chrome')
})
it('returns path and chrome given just nix path', () => {
const browserPath = 'C:/foo/bar/chrome.exe'
const res = windowsHelper.getPathData(browserPath)
expect(res.path).to.eq(windowsHelper.doubleEscape(browserPath))
expect(res.browserKey).to.eq('chrome')
})
it('returns path and edge given just path for edge', () => {
const browserPath = 'C:\\foo\\bar\\edge.exe'
const res = windowsHelper.getPathData(browserPath)
expect(res.path).to.eq(windowsHelper.doubleEscape(browserPath))
expect(res.browserKey).to.eq('edge')
})
it('returns path and edge given just path for msedge', () => {
const browserPath = 'C:\\foo\\bar\\msedge.exe'
const res = windowsHelper.getPathData(browserPath)
expect(res.path).to.eq(windowsHelper.doubleEscape(browserPath))
expect(res.browserKey).to.eq('edge')
})
it('returns path and edge given just nix path', () => {
const browserPath = 'C:/foo/bar/edge.exe'
const res = windowsHelper.getPathData(browserPath)
expect(res.path).to.eq(windowsHelper.doubleEscape(browserPath))
expect(res.browserKey).to.eq('edge')
})
it('returns path and edge given just nix path for msedge', () => {
const browserPath = 'C:/foo/bar/msedge.exe'
const res = windowsHelper.getPathData(browserPath)
expect(res.path).to.eq(windowsHelper.doubleEscape(browserPath))
expect(res.browserKey).to.eq('edge')
})
it('returns path and firefox given just path', () => {
const browserPath = 'C:\\foo\\bar\\firefox.exe'
const res = windowsHelper.getPathData(browserPath)
expect(res.path).to.eq(windowsHelper.doubleEscape(browserPath))
expect(res.browserKey).to.eq('firefox')
})
it('returns path and firefox given just nix path', () => {
const browserPath = 'C:/foo/bar/firefox.exe'
const res = windowsHelper.getPathData(browserPath)
expect(res.path).to.eq(windowsHelper.doubleEscape(browserPath))
expect(res.browserKey).to.eq('firefox')
})
})
context('#doubleEscape', () => {
let winPath = 'C:\\\\foo\\\\bar.exe'
it('converts nix path into double escaped win path', async () => {
let nixPath = 'C:/foo/bar.exe'
expect(windowsHelper.doubleEscape(nixPath)).to.eq(winPath)
})
it('converts win path with different backslash combination into double escaped win path', async () => {
let badWinPath = 'C:\\\\\\\\\\foo\\bar.exe'
expect(windowsHelper.doubleEscape(badWinPath)).to.eq(winPath)
})
it('converts single escaped win path into double escaped win path', async () => {
let badWinPath = 'C:\\foo\\bar.exe'
expect(windowsHelper.doubleEscape(badWinPath)).to.eq(winPath)
})
it('does not affect an already double escaped win path', async () => {
let badWinPath = 'C:\\\\foo\\\\bar.exe'
expect(windowsHelper.doubleEscape(badWinPath)).to.eq(badWinPath)
})
})
})
+9
View File
@@ -0,0 +1,9 @@
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
include: ['test/**/*.spec.ts'],
globals: true,
environment: 'node',
},
})
+3 -15
View File
@@ -7107,7 +7107,7 @@
resolved "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz#719df7fb41766bc143369eaa0dd56d8dc87c9958"
integrity sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==
"@sinonjs/commons@^1", "@sinonjs/commons@^1.3.0", "@sinonjs/commons@^1.4.0", "@sinonjs/commons@^1.6.0", "@sinonjs/commons@^1.7.0", "@sinonjs/commons@^1.7.2", "@sinonjs/commons@^1.8.1", "@sinonjs/commons@^1.8.3":
"@sinonjs/commons@^1", "@sinonjs/commons@^1.3.0", "@sinonjs/commons@^1.4.0", "@sinonjs/commons@^1.6.0", "@sinonjs/commons@^1.7.0", "@sinonjs/commons@^1.7.2", "@sinonjs/commons@^1.8.3":
version "1.8.6"
resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.6.tgz#80c516a4dc264c2a69115e7578d62581ff455ed9"
integrity sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==
@@ -7205,7 +7205,7 @@
lodash.get "^4.4.2"
type-detect "^4.0.8"
"@sinonjs/samsam@^5.0.2", "@sinonjs/samsam@^5.0.3", "@sinonjs/samsam@^5.3.1":
"@sinonjs/samsam@^5.0.2", "@sinonjs/samsam@^5.0.3":
version "5.3.1"
resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-5.3.1.tgz#375a45fe6ed4e92fca2fb920e007c48232a6507f"
integrity sha512-1Hc0b1TtyfBu8ixF/tpfSHTVWKwCBLY4QJbkgnE7HcwyvT2xArDxb4K7dMgqRm3szI+LJbzmW/s4xxEhv6hwDg==
@@ -24494,7 +24494,7 @@ nise@^3.0.1:
lolex "^5.0.1"
path-to-regexp "^1.7.0"
nise@^4.0.1, nise@^4.1.0:
nise@^4.0.1:
version "4.1.0"
resolved "https://registry.yarnpkg.com/nise/-/nise-4.1.0.tgz#8fb75a26e90b99202fa1e63f448f58efbcdedaf6"
integrity sha512-eQMEmGN/8arp0xsvGoQ+B1qvSkR73B1nWSCh7nOt5neMCtwcQVYQGdzQMhcNscktTsWB54xnlSQFzOAPJD8nXA==
@@ -29683,18 +29683,6 @@ sinon@8.1.1:
nise "^3.0.1"
supports-color "^7.1.0"
sinon@^10.0.0:
version "10.0.0"
resolved "https://registry.yarnpkg.com/sinon/-/sinon-10.0.0.tgz#52279f97e35646ff73d23207d0307977c9b81430"
integrity sha512-XAn5DxtGVJBlBWYrcYKEhWCz7FLwZGdyvANRyK06419hyEpdT0dMc5A8Vcxg5SCGHc40CsqoKsc1bt1CbJPfNw==
dependencies:
"@sinonjs/commons" "^1.8.1"
"@sinonjs/fake-timers" "^6.0.1"
"@sinonjs/samsam" "^5.3.1"
diff "^4.0.2"
nise "^4.1.0"
supports-color "^7.1.0"
sinon@^9.0.0:
version "9.0.2"
resolved "https://registry.yarnpkg.com/sinon/-/sinon-9.0.2.tgz#b9017e24633f4b1c98dfb6e784a5f0509f5fd85d"