mirror of
https://github.com/cypress-io/cypress.git
synced 2026-05-01 20:39:57 -05:00
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:
@@ -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
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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',
|
||||
},
|
||||
},
|
||||
]
|
||||
@@ -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')
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
test/unit
|
||||
--compilers ts:@packages/ts/register
|
||||
--timeout 10000
|
||||
--recursive
|
||||
@@ -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,
|
||||
},
|
||||
]
|
||||
`;
|
||||
+10
-11
@@ -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.')
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -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')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -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')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -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',
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -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',
|
||||
}),
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -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)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -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)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -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)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -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)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,9 @@
|
||||
import { defineConfig } from 'vitest/config'
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
include: ['test/**/*.spec.ts'],
|
||||
globals: true,
|
||||
environment: 'node',
|
||||
},
|
||||
})
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user