mirror of
https://github.com/cypress-io/cypress.git
synced 2026-01-30 11:00:35 -06:00
launcher: detect chrome on windows (#504)
close #504 * launcher: detect chrome on windows checks if file exists, then determines version using `wmic` close #503 * launcher: detect canary and chromium plus update types to latest * add launcher as a CI job * run launcher on Windows CI * forgot to restore monorepo * go back on Win CI
This commit is contained in:
@@ -21,6 +21,7 @@ test_script:
|
||||
# Output useful info for debugging.
|
||||
- node --version
|
||||
- npm --version
|
||||
- cd packages/launcher && node index.js && cd ../..
|
||||
- npm run binary-build -- --platform windows --version 0.20.2-win
|
||||
# - cd packages/server && npm run test-unit
|
||||
# - npm test
|
||||
|
||||
10
circle.yml
10
circle.yml
@@ -367,6 +367,13 @@ jobs:
|
||||
- store_artifacts:
|
||||
path: /tmp/artifacts
|
||||
|
||||
"run-launcher":
|
||||
<<: *defaults
|
||||
steps:
|
||||
- restore_cache:
|
||||
key: cypress-monorepo-{{ .Branch }}-{{ .Revision }}
|
||||
- run: cd packages/launcher && node index.js
|
||||
|
||||
"build-binary":
|
||||
<<: *defaults
|
||||
steps:
|
||||
@@ -433,6 +440,9 @@ workflows:
|
||||
- build-binary:
|
||||
requires:
|
||||
- build
|
||||
- run-launcher:
|
||||
requires:
|
||||
- build
|
||||
|
||||
#
|
||||
# things to run in the 4th CI container
|
||||
|
||||
@@ -9,6 +9,10 @@ to output debug log messages. To turn on, use
|
||||
DEBUG=cypress:launcher npm test
|
||||
```
|
||||
|
||||
## Demo
|
||||
|
||||
To see browsers detected on your machine, just run `node index.js`
|
||||
|
||||
## Changelog
|
||||
|
||||
#### 0.1.1 - *(04/20/17)*
|
||||
|
||||
@@ -14,8 +14,10 @@ if (!module.parent) {
|
||||
console.log('Launcher project exports')
|
||||
console.log(launcher)
|
||||
console.log('⛔️ please use it as a module, not from CLI')
|
||||
|
||||
const pluralize = require('pluralize')
|
||||
launcher.detect().then((browsers) => {
|
||||
console.log('detected %d browser(s)', browsers.length)
|
||||
console.log('detected %s', pluralize('browser', browsers.length, true))
|
||||
console.log(browsers)
|
||||
}, console.error)
|
||||
/* eslint-enable no-console */
|
||||
|
||||
@@ -24,7 +24,8 @@ export function parse(p: string, property: string): Promise<string> {
|
||||
.readFile(pl, 'utf8')
|
||||
.then(plist.parse)
|
||||
.then(prop(property))
|
||||
.catch(failed)
|
||||
.then(String) // explicitly convert value to String type
|
||||
.catch(failed) // to make TS compiler happy
|
||||
}
|
||||
|
||||
/** uses mdfind to find app using Ma app id like 'com.google.Chrome.canary' */
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { log } from '../log'
|
||||
import { FoundBrowser, Browser, NotInstalledError } from '../types'
|
||||
import * as Promise from 'bluebird'
|
||||
import * as execa from 'execa'
|
||||
import { normalize, join } from 'path'
|
||||
import { prop, trim, tap } from 'ramda'
|
||||
import { pathExists } from 'fs-extra'
|
||||
import { homedir } from 'os'
|
||||
|
||||
const notInstalledErr = (name: string) => {
|
||||
const err: NotInstalledError = new Error(
|
||||
@@ -10,20 +14,102 @@ const notInstalledErr = (name: string) => {
|
||||
return err
|
||||
}
|
||||
|
||||
function formFullAppPath(name: string) {
|
||||
const prefix = 'C:/Program Files (x86)/Google/Chrome/Application'
|
||||
return normalize(join(prefix, `${name}.exe`))
|
||||
}
|
||||
|
||||
function formChromiumAppPath() {
|
||||
const exe = 'C:/Program Files (x86)/Google/chrome-win32/chrome.exe'
|
||||
return normalize(exe)
|
||||
}
|
||||
|
||||
function formChromeCanaryAppPath() {
|
||||
const home = homedir()
|
||||
const exe = join(
|
||||
home,
|
||||
'AppData',
|
||||
'Local',
|
||||
'Google',
|
||||
'Chrome SxS',
|
||||
'Application',
|
||||
'chrome.exe'
|
||||
)
|
||||
return normalize(exe)
|
||||
}
|
||||
|
||||
type NameToPath = (name: string) => string
|
||||
|
||||
interface WindowsBrowserPaths {
|
||||
[index: string]: NameToPath
|
||||
chrome: NameToPath
|
||||
canary: NameToPath
|
||||
chromium: NameToPath
|
||||
}
|
||||
|
||||
const formPaths: WindowsBrowserPaths = {
|
||||
chrome: formFullAppPath,
|
||||
canary: formChromeCanaryAppPath,
|
||||
chromium: formChromiumAppPath
|
||||
}
|
||||
|
||||
function getWindowsBrowser(
|
||||
name: string,
|
||||
binary: string,
|
||||
versionRegex: RegExp
|
||||
binary: string
|
||||
): Promise<FoundBrowser> {
|
||||
log(
|
||||
'Cannot detect windows browser yet "%s" binary "%s" version "%s"',
|
||||
name,
|
||||
binary,
|
||||
versionRegex
|
||||
)
|
||||
return Promise.reject(notInstalledErr(name))
|
||||
const getVersion = (stdout: string): string => {
|
||||
// result from wmic datafile
|
||||
// "Version=61.0.3163.100"
|
||||
const wmicVersion = /^Version=(\S+)$/
|
||||
const m = wmicVersion.exec(stdout)
|
||||
if (m) {
|
||||
return m[1]
|
||||
}
|
||||
log('Could not extract version from %s using regex %s', stdout, wmicVersion)
|
||||
throw notInstalledErr(binary)
|
||||
}
|
||||
|
||||
const formFullAppPathFn: any = formPaths[name] || formFullAppPath
|
||||
const exePath = formFullAppPathFn(name)
|
||||
log('exe path %s', exePath)
|
||||
|
||||
const doubleEscape = (s: string) => s.replace(/\\/g, '\\\\')
|
||||
|
||||
return pathExists(exePath)
|
||||
.then(exists => {
|
||||
console.log('found %s ?', exePath, exists)
|
||||
if (!exists) {
|
||||
throw notInstalledErr(`Browser ${name} file not found at ${exePath}`)
|
||||
}
|
||||
// on Windows using "--version" seems to always start the full
|
||||
// browser, no matter what one does.
|
||||
const args: [string] = [
|
||||
'datafile',
|
||||
'where',
|
||||
`name="${doubleEscape(exePath)}"`,
|
||||
'get',
|
||||
'Version',
|
||||
'/value'
|
||||
]
|
||||
return execa('wmic', args)
|
||||
.then(prop('stdout'))
|
||||
.then(trim)
|
||||
.then(tap(log))
|
||||
.then(getVersion)
|
||||
.then((version: string) => {
|
||||
log("browser %s at '%s' version %s", name, exePath, version)
|
||||
return {
|
||||
name,
|
||||
version,
|
||||
path: exePath
|
||||
}
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
throw notInstalledErr(name)
|
||||
})
|
||||
}
|
||||
|
||||
export function detectBrowserWindows(browser: Browser) {
|
||||
return getWindowsBrowser(browser.name, browser.binary, browser.versionRegex)
|
||||
return getWindowsBrowser(browser.name, browser.binary)
|
||||
}
|
||||
|
||||
@@ -11,10 +11,9 @@
|
||||
"clean-deps": "rm -rf node_modules",
|
||||
"clean": "rm lib/*.js lib/**/*.js || true",
|
||||
"clean-js": "npm run clean",
|
||||
"lint": "npm run format-ts && npm run lint-ts && npm run lint-coffee && npm run lint-js",
|
||||
"lint": "npm run format-ts && npm run lint-ts && npm run lint-js",
|
||||
"lint-js": "bin-up eslint --fix *.js",
|
||||
"lint-ts": "tslint --type-check --project . --fix --format stylish lib/*.ts lib/**/*.ts",
|
||||
"lint-coffee": "bin-up coffeelint test/*.coffee test/**/*.coffee",
|
||||
"format-ts": "prettier --no-semi --single-quote --write lib/*.ts lib/**/*.ts",
|
||||
"build-js": "tsc",
|
||||
"size": "t=\"$(npm pack .)\"; wc -c \"${t}\"; tar tvf \"${t}\"; rm \"${t}\";"
|
||||
@@ -27,27 +26,29 @@
|
||||
"@types/bluebird": "^3.5.3",
|
||||
"@types/chai": "^3.5.2",
|
||||
"@types/debug": "0.0.29",
|
||||
"@types/execa": "^0.7.0",
|
||||
"@types/fs-extra": "3.0.0",
|
||||
"@types/lodash": "^4.14.64",
|
||||
"@types/mocha": "^2.2.41",
|
||||
"@types/node": "^7.0.18",
|
||||
"bin-up": "^1.1.0",
|
||||
"chai": "^3.5.0",
|
||||
"prettier": "^1.4.2",
|
||||
"prettier": "^1.7.0",
|
||||
"sinon": "^1.17.3",
|
||||
"sinon-chai": "^2.8.0",
|
||||
"tslint": "5.4.3",
|
||||
"tslint-config-standard": "5.0.2",
|
||||
"typescript": "2.3.2"
|
||||
"tslint": "5.7.0",
|
||||
"tslint-config-standard": "6.0.1",
|
||||
"typescript": "^2.5.2",
|
||||
"@types/ramda": "0.24.14"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/ramda": "0.0.10",
|
||||
"bluebird": "^3.5.0",
|
||||
"debug": "^2.6.6",
|
||||
"execa": "^0.6.3",
|
||||
"fs-extra": "^3.0.0",
|
||||
"lodash": "^4.11.1",
|
||||
"plist": "^2.1.0",
|
||||
"ramda": "^0.23.0"
|
||||
"pluralize": "^7.0.0",
|
||||
"ramda": "^0.24.1"
|
||||
}
|
||||
}
|
||||
|
||||
12
packages/ts/index.d.ts
vendored
12
packages/ts/index.d.ts
vendored
@@ -1,15 +1,7 @@
|
||||
// missing type definitions for 3rd party libraries
|
||||
// https://glebbahmutov.com/blog/trying-typescript/#manual-types-for-3rd-party-libraries
|
||||
declare module 'execa' {
|
||||
type ExecaResult = {
|
||||
stdout: string
|
||||
}
|
||||
interface Execa {
|
||||
shell: (cmd:string) => Promise<ExecaResult>
|
||||
}
|
||||
const execa: Execa
|
||||
export = execa
|
||||
}
|
||||
|
||||
// for execa module use @types/execa
|
||||
|
||||
declare module 'plist' {
|
||||
interface Plist {
|
||||
|
||||
Reference in New Issue
Block a user