Merge branch 'develop' into v6.0-release

This commit is contained in:
Jennifer Shehane
2020-11-17 22:38:39 +06:30
committed by GitHub
26 changed files with 383 additions and 74 deletions
-1
View File
@@ -34,7 +34,6 @@ Thanks for taking the time to contribute! :smile:
- [Committing Code](#committing-code)
- [Branches](#branches)
- [Pull Requests](#pull-requests)
- [Testing](#testing)
- [Dependencies](#dependencies)
- [Reviewing Code](#reviewing-code)
- [Some rules about Code Review](#Some-rules-about-Code-Review)
+10 -1
View File
@@ -9,6 +9,7 @@ macBuildFilters: &macBuildFilters
only:
- develop
- v6.0-release
- include-electron-node-version
defaults: &defaults
parallelism: 1
@@ -309,6 +310,10 @@ commands:
working_directory: /tmp/<<parameters.repo>>
# force installing the freshly built binary
command: CYPRESS_INSTALL_BINARY=~/cypress/cypress.zip npm i ~/cypress/cypress.tgz
- run:
name: Print Cypress version
working_directory: /tmp/<<parameters.repo>>
command: npx cypress version
- run:
name: Types check 🧩 (maybe)
working_directory: /tmp/<<parameters.repo>>
@@ -1045,7 +1050,7 @@ jobs:
environment:
DEBUG: electron-builder,electron-osx-sign*
# notarization on Mac can take a while
no_output_timeout: "30m"
no_output_timeout: "45m"
# if this is a forked pull request, the NEXT_DEV_VERSION environment variable
# won't be set and we will use default version, since we are not going to
# upload the dev binary build anywhere
@@ -1287,6 +1292,10 @@ jobs:
working_directory: test-binary
# force installing the freshly built binary
command: CYPRESS_INSTALL_BINARY=/root/cypress/cypress.zip npm i /root/cypress/cypress.tgz
- run:
name: Cypress version
working_directory: test-binary
command: $(yarn bin)/cypress version
- run:
name: Verify Cypress binary
working_directory: test-binary
+1 -1
View File
@@ -12,7 +12,7 @@ After installing you'll be able to:
## Install
Requires Node version >= 4.0.0
Requires Node version >= 10.0.0
```sh
npm install --save-dev cypress
+21
View File
@@ -359,26 +359,43 @@ exports['cli CYPRESS_INTERNAL_ENV catches environment "foo" 1'] = `
exports['cli version and binary version 1'] = `
Cypress package version: 1.2.3
Cypress binary version: X.Y.Z
Electron version: not found
Bundled Node version: not found
`
exports['cli version and binary version 2'] = `
Cypress package version: 1.2.3
Cypress binary version: X.Y.Z
Electron version: not found
Bundled Node version: not found
`
exports['cli version with electron and node 1'] = `
Cypress package version: 1.2.3
Cypress binary version: X.Y.Z
Electron version: 10.10.88
Bundled Node version: 11.10.3
`
exports['cli version no binary version 1'] = `
Cypress package version: 1.2.3
Cypress binary version: not installed
Electron version: not found
Bundled Node version: not found
`
exports['cli --version no binary version 1'] = `
Cypress package version: 1.2.3
Cypress binary version: not installed
Electron version: not found
Bundled Node version: not found
`
exports['cli -v no binary version 1'] = `
Cypress package version: 1.2.3
Cypress binary version: not installed
Electron version: not found
Bundled Node version: not found
`
exports['cli cypress run warns with space-separated --spec 1'] = `
@@ -445,11 +462,15 @@ exports['cli CYPRESS_INTERNAL_ENV allows and warns when staging environment 1']
exports['cli version and binary version with npm log silent'] = `
Cypress package version: 1.2.3
Cypress binary version: X.Y.Z
Electron version: not found
Bundled Node version: not found
`
exports['cli version and binary version with npm log warn'] = `
Cypress package version: 1.2.3
Cypress binary version: X.Y.Z
Electron version: not found
Bundled Node version: not found
`
exports['prints explanation when no cache'] = `
+2
View File
@@ -168,6 +168,8 @@ function showVersions () {
.then((versions = {}) => {
logger.always('Cypress package version:', versions.package)
logger.always('Cypress binary version:', versions.binary)
logger.always('Electron version:', versions.electronVersion)
logger.always('Bundled Node version:', versions.electronNodeVersion)
process.exit(0)
})
.catch(util.logErrorExit1)
+22 -5
View File
@@ -28,12 +28,29 @@ const getVersions = () => {
return state.getBinaryDir()
})
.then(state.getBinaryPkgVersionAsync)
.then((binaryVersion) => {
return {
package: util.pkgVersion(),
binary: binaryVersion || 'not installed',
.then(state.getBinaryPkgAsync)
.then((pkg) => {
const versions = {
binary: state.getBinaryPkgVersion(pkg),
electronVersion: state.getBinaryElectronVersion(pkg),
electronNodeVersion: state.getBinaryElectronNodeVersion(pkg),
}
debug('binary versions %o', versions)
return versions
})
.then((binaryVersions) => {
const versions = {
package: util.pkgVersion(),
binary: binaryVersions.binary || 'not installed',
electronVersion: binaryVersions.electronVersion || 'not found',
electronNodeVersion: binaryVersions.electronNodeVersion || 'not found',
}
debug('combined versions %o', versions)
return versions
})
}
+1 -1
View File
@@ -281,7 +281,7 @@ const start = (options = {}) => {
})
.then(() => {
return Promise.all([
state.getBinaryPkgVersionAsync(binaryDir),
state.getBinaryPkgAsync(binaryDir).then(state.getBinaryPkgVersion),
getVersionSpecifier(),
])
})
+15 -3
View File
@@ -2,6 +2,7 @@ const _ = require('lodash')
const os = require('os')
const path = require('path')
const untildify = require('untildify')
const R = require('ramda')
const debug = require('debug')('cypress:cli')
const fs = require('../fs')
@@ -159,7 +160,11 @@ const getPathToExecutable = (binaryDir) => {
return path.join(binaryDir, getPlatformExecutable())
}
const getBinaryPkgVersionAsync = (binaryDir) => {
/**
* Resolves with an object read from the binary app package.json file.
* If the file does not exist resolves with null
*/
const getBinaryPkgAsync = (binaryDir) => {
const pathToPackageJson = getBinaryPkgPath(binaryDir)
debug('Reading binary package.json from:', pathToPackageJson)
@@ -171,15 +176,22 @@ const getBinaryPkgVersionAsync = (binaryDir) => {
}
return fs.readJsonAsync(pathToPackageJson)
.get('version')
})
}
const getBinaryPkgVersion = R.propOr(null, 'version')
const getBinaryElectronVersion = R.propOr(null, 'electronVersion')
const getBinaryElectronNodeVersion = R.propOr(null, 'electronNodeVersion')
module.exports = {
getPathToExecutable,
getPlatformExecutable,
getBinaryPkgVersionAsync,
// those names start to sound like Java
getBinaryElectronNodeVersion,
getBinaryElectronVersion,
getBinaryPkgVersion,
getBinaryVerifiedAsync,
getBinaryPkgAsync,
getBinaryPkgPath,
getBinaryDir,
getCacheDir,
+4 -1
View File
@@ -318,7 +318,10 @@ const start = (options = {}) => {
return debug('binaryDir is ', binaryDir)
})
.then(() => {
return state.getBinaryPkgVersionAsync(binaryDir)
return state.getBinaryPkgAsync(binaryDir)
})
.then((pkg) => {
return state.getBinaryPkgVersion(pkg)
})
.then((binaryVersion) => {
if (!binaryVersion) {
+27 -8
View File
@@ -151,9 +151,11 @@ describe('cli', () => {
it('reports package version', (done) => {
sinon.stub(util, 'pkgVersion').returns('1.2.3')
sinon
.stub(state, 'getBinaryPkgVersionAsync')
.stub(state, 'getBinaryPkgAsync')
.withArgs(binaryDir)
.resolves('X.Y.Z')
.resolves({
version: 'X.Y.Z',
})
this.exec('version')
process.exit.callsFake(() => {
@@ -164,7 +166,7 @@ describe('cli', () => {
it('reports package and binary message', (done) => {
sinon.stub(util, 'pkgVersion').returns('1.2.3')
sinon.stub(state, 'getBinaryPkgVersionAsync').resolves('X.Y.Z')
sinon.stub(state, 'getBinaryPkgAsync').resolves({ version: 'X.Y.Z' })
this.exec('version')
process.exit.callsFake(() => {
@@ -173,13 +175,28 @@ describe('cli', () => {
})
})
it('reports electron and node message', (done) => {
sinon.stub(util, 'pkgVersion').returns('1.2.3')
sinon.stub(state, 'getBinaryPkgAsync').resolves({
version: 'X.Y.Z',
electronVersion: '10.10.88',
electronNodeVersion: '11.10.3',
})
this.exec('version')
process.exit.callsFake(() => {
snapshot('cli version with electron and node 1', logger.print())
done()
})
})
it('reports package and binary message with npm log silent', (done) => {
restoreEnv = mockedEnv({
npm_config_loglevel: 'silent',
})
sinon.stub(util, 'pkgVersion').returns('1.2.3')
sinon.stub(state, 'getBinaryPkgVersionAsync').resolves('X.Y.Z')
sinon.stub(state, 'getBinaryPkgAsync').resolves({ version: 'X.Y.Z' })
this.exec('version')
process.exit.callsFake(() => {
@@ -195,7 +212,9 @@ describe('cli', () => {
})
sinon.stub(util, 'pkgVersion').returns('1.2.3')
sinon.stub(state, 'getBinaryPkgVersionAsync').resolves('X.Y.Z')
sinon.stub(state, 'getBinaryPkgAsync').resolves({
version: 'X.Y.Z',
})
this.exec('version')
process.exit.callsFake(() => {
@@ -207,7 +226,7 @@ describe('cli', () => {
it('handles non-existent binary version', (done) => {
sinon.stub(util, 'pkgVersion').returns('1.2.3')
sinon.stub(state, 'getBinaryPkgVersionAsync').resolves(null)
sinon.stub(state, 'getBinaryPkgAsync').resolves(null)
this.exec('version')
process.exit.callsFake(() => {
@@ -218,7 +237,7 @@ describe('cli', () => {
it('handles non-existent binary --version', (done) => {
sinon.stub(util, 'pkgVersion').returns('1.2.3')
sinon.stub(state, 'getBinaryPkgVersionAsync').resolves(null)
sinon.stub(state, 'getBinaryPkgAsync').resolves(null)
this.exec('--version')
process.exit.callsFake(() => {
@@ -229,7 +248,7 @@ describe('cli', () => {
it('handles non-existent binary -v', (done) => {
sinon.stub(util, 'pkgVersion').returns('1.2.3')
sinon.stub(state, 'getBinaryPkgVersionAsync').resolves(null)
sinon.stub(state, 'getBinaryPkgAsync').resolves(null)
this.exec('-v')
process.exit.callsFake(() => {
+40 -6
View File
@@ -1,3 +1,5 @@
const { expect } = require('chai')
require('../../spec_helper')
const util = require(`${lib}/util`)
@@ -5,31 +7,63 @@ const state = require(`${lib}/tasks/state`)
const versions = require(`${lib}/exec/versions`)
describe('lib/exec/versions', function () {
const binaryDir = '/cache/1.2.3/Cypress.app'
beforeEach(function () {
sinon.stub(state, 'getBinaryDir').returns('/cache/1.2.3/Cypress.app')
sinon.stub(state, 'getBinaryPkgVersionAsync').withArgs('/cache/1.2.3/Cypress.app').resolves('1.2.3')
sinon.stub(state, 'getBinaryDir').returns(binaryDir)
sinon.stub(state, 'getBinaryPkgAsync').withArgs(binaryDir).resolves({
version: '1.2.3',
electronVersion: '10.1.2',
electronNodeVersion: '12.16.3',
})
sinon.stub(util, 'pkgVersion').returns('4.5.6')
})
describe('.getVersions', function () {
it('gets the correct binary and package version', function () {
return versions.getVersions().then(({ package, binary }) => {
expect(package).to.eql('4.5.6')
expect(binary).to.eql('1.2.3')
expect(package, 'package version').to.eql('4.5.6')
expect(binary, 'binary version').to.eql('1.2.3')
})
})
it('gets the correct Electron and bundled Node version', function () {
return versions.getVersions().then(({ electronVersion, electronNodeVersion }) => {
expect(electronVersion, 'electron version').to.eql('10.1.2')
expect(electronNodeVersion, 'node version').to.eql('12.16.3')
})
})
it('gets correct binary version if CYPRESS_RUN_BINARY', function () {
sinon.stub(state, 'parseRealPlatformBinaryFolderAsync').resolves('/my/cypress/path')
process.env.CYPRESS_RUN_BINARY = '/my/cypress/path'
state.getBinaryPkgVersionAsync
state.getBinaryPkgAsync
.withArgs('/my/cypress/path')
.resolves('7.8.9')
.resolves({
version: '7.8.9',
})
return versions.getVersions().then(({ package, binary }) => {
expect(package).to.eql('4.5.6')
expect(binary).to.eql('7.8.9')
})
})
it('reports default versions if not found', function () {
// imagine package.json only has version there
state.getBinaryPkgAsync.withArgs(binaryDir).resolves({
version: '90.9.9',
})
return versions.getVersions().then((versions) => {
expect(versions).to.deep.equal({
'package': '4.5.6',
'binary': '90.9.9',
'electronVersion': 'not found',
'electronNodeVersion': 'not found',
})
})
})
})
})
+13 -13
View File
@@ -55,7 +55,7 @@ describe('/lib/tasks/install', function () {
sinon.stub(fs, 'removeAsync').resolves()
sinon.stub(state, 'getVersionDir').returns('/cache/Cypress/1.2.3')
sinon.stub(state, 'getBinaryDir').returns('/cache/Cypress/1.2.3/Cypress.app')
sinon.stub(state, 'getBinaryPkgVersionAsync').resolves()
sinon.stub(state, 'getBinaryPkgAsync').resolves()
sinon.stub(fs, 'ensureDirAsync').resolves(undefined)
os.platform.returns('darwin')
})
@@ -181,14 +181,14 @@ describe('/lib/tasks/install', function () {
describe('when version is already installed', function () {
beforeEach(function () {
state.getBinaryPkgVersionAsync.resolves(packageVersion)
state.getBinaryPkgAsync.resolves({ version: packageVersion })
})
it('doesn\'t attempt to download', function () {
return install.start()
.then(() => {
expect(download.start).not.to.be.called
expect(state.getBinaryPkgVersionAsync).to.be.calledWith('/cache/Cypress/1.2.3/Cypress.app')
expect(state.getBinaryPkgAsync).to.be.calledWith('/cache/Cypress/1.2.3/Cypress.app')
})
})
@@ -217,7 +217,7 @@ describe('/lib/tasks/install', function () {
describe('when getting installed version fails', function () {
beforeEach(function () {
state.getBinaryPkgVersionAsync.resolves(null)
state.getBinaryPkgAsync.resolves(null)
return install.start()
})
@@ -240,7 +240,7 @@ describe('/lib/tasks/install', function () {
describe('when there is no install version', function () {
beforeEach(function () {
state.getBinaryPkgVersionAsync.resolves(null)
state.getBinaryPkgAsync.resolves(null)
return install.start()
})
@@ -268,7 +268,7 @@ describe('/lib/tasks/install', function () {
describe('when getting installed version does not match needed version', function () {
beforeEach(function () {
state.getBinaryPkgVersionAsync.resolves('x.x.x')
state.getBinaryPkgAsync.resolves({ version: 'x.x.x' })
return install.start()
})
@@ -291,7 +291,7 @@ describe('/lib/tasks/install', function () {
describe('with force: true', function () {
beforeEach(function () {
state.getBinaryPkgVersionAsync.resolves(packageVersion)
state.getBinaryPkgAsync.resolves({ version: packageVersion })
return install.start({ force: true })
})
@@ -316,7 +316,7 @@ describe('/lib/tasks/install', function () {
beforeEach(function () {
sinon.stub(util, 'isInstalledGlobally').returns(true)
state.getBinaryPkgVersionAsync.resolves('x.x.x')
state.getBinaryPkgAsync.resolves({ version: 'x.x.x' })
return install.start()
})
@@ -341,7 +341,7 @@ describe('/lib/tasks/install', function () {
beforeEach(function () {
util.isCi.returns(true)
state.getBinaryPkgVersionAsync.resolves('x.x.x')
state.getBinaryPkgAsync.resolves({ version: 'x.x.x' })
return install.start()
})
@@ -381,7 +381,7 @@ describe('/lib/tasks/install', function () {
describe('CYPRESS_INSTALL_BINARY is URL or Zip', function () {
it('uses cache when correct version installed given URL', function () {
state.getBinaryPkgVersionAsync.resolves('1.2.3')
state.getBinaryPkgAsync.resolves({ version: '1.2.3' })
util.pkgVersion.returns('1.2.3')
process.env.CYPRESS_INSTALL_BINARY = 'www.cypress.io/cannot-download/2.4.5'
@@ -392,7 +392,7 @@ describe('/lib/tasks/install', function () {
})
it('uses cache when mismatch version given URL ', function () {
state.getBinaryPkgVersionAsync.resolves('1.2.3')
state.getBinaryPkgAsync.resolves({ version: '1.2.3' })
util.pkgVersion.returns('4.0.0')
process.env.CYPRESS_INSTALL_BINARY = 'www.cypress.io/cannot-download/2.4.5'
@@ -405,7 +405,7 @@ describe('/lib/tasks/install', function () {
it('uses cache when correct version installed given Zip', function () {
sinon.stub(fs, 'pathExistsAsync').withArgs('/path/to/zip.zip').resolves(true)
state.getBinaryPkgVersionAsync.resolves('1.2.3')
state.getBinaryPkgAsync.resolves({ version: '1.2.3' })
util.pkgVersion.returns('1.2.3')
process.env.CYPRESS_INSTALL_BINARY = '/path/to/zip.zip'
@@ -419,7 +419,7 @@ describe('/lib/tasks/install', function () {
it('uses cache when mismatch version given Zip ', function () {
sinon.stub(fs, 'pathExistsAsync').withArgs('/path/to/zip.zip').resolves(true)
state.getBinaryPkgVersionAsync.resolves('1.2.3')
state.getBinaryPkgAsync.resolves({ version: '1.2.3' })
util.pkgVersion.returns('4.0.0')
process.env.CYPRESS_INSTALL_BINARY = '/path/to/zip.zip'
+21 -10
View File
@@ -5,6 +5,7 @@ const path = require('path')
const Promise = require('bluebird')
const proxyquire = require('proxyquire')
const mockfs = require('mock-fs')
const { expect } = require('chai')
const debug = require('debug')('test')
const fs = require(`${lib}/fs`)
@@ -32,8 +33,18 @@ describe('lib/tasks/state', function () {
os.platform.returns('darwin')
})
context('.getBinaryPkgVersionAsync', function () {
it('resolves version from version file when it exists', function () {
context('.getBinaryPkgVersion', function () {
it('returns version if present', () => {
expect(state.getBinaryPkgVersion({ version: '1.2.3' })).to.equal('1.2.3')
})
it('returns null if passed null', () => {
expect(state.getBinaryPkgVersion(null)).to.equal(null)
})
})
context('.getBinaryPkgAsync', function () {
it('resolves with loaded file when the file exists', function () {
sinon
.stub(fs, 'pathExistsAsync')
.withArgs(binaryPkgPath)
@@ -44,8 +55,8 @@ describe('lib/tasks/state', function () {
.withArgs(binaryPkgPath)
.resolves({ version: '2.0.48' })
return state.getBinaryPkgVersionAsync(binaryDir).then((binaryVersion) => {
expect(binaryVersion).to.equal('2.0.48')
return state.getBinaryPkgAsync(binaryDir).then((result) => {
expect(result).to.deep.equal({ version: '2.0.48' })
})
})
@@ -53,9 +64,9 @@ describe('lib/tasks/state', function () {
sinon.stub(fs, 'pathExistsAsync').resolves(false)
return state
.getBinaryPkgVersionAsync(binaryDir)
.then((binaryVersion) => {
return expect(binaryVersion).to.equal(null)
.getBinaryPkgAsync(binaryDir)
.then((result) => {
return expect(result).to.equal(null)
})
})
@@ -75,9 +86,9 @@ describe('lib/tasks/state', function () {
.resolves({ version: '3.4.5' })
return state
.getBinaryPkgVersionAsync(customBinaryDir)
.then((binaryVersion) => {
return expect(binaryVersion).to.equal('3.4.5')
.getBinaryPkgAsync(customBinaryDir)
.then((result) => {
return expect(result).to.deep.equal({ version: '3.4.5' })
})
})
})
+1
View File
@@ -19,6 +19,7 @@
"check-terminal": "node scripts/check-terminal.js",
"clean": "lerna run clean --parallel",
"clean-deps": "find . -depth -name node_modules -type d -exec rm -rf {} \\;",
"clean-untracked-files": "git clean -d -f",
"precypress:open": "yarn ensure-deps",
"cypress:open": "node $(yarn bin cypress) open --dev --global",
"precypress:open:debug": "yarn ensure-deps",
@@ -729,6 +729,31 @@ describe('Specs List', function () {
cy.contains('.all-tests', 'Run 8 component specs')
})
})
context('returning to specs tab', function () {
beforeEach(function () {
this.ipc.getSpecs.yields(null, this.specs)
this.openProject.resolve(this.config)
})
// https://github.com/cypress-io/cypress/issues/9151
it('does not crash when running', function () {
cy.contains('.file-name', 'app_spec.coffee').click()
.then(function () {
this.ipc.onSpecChanged.yield(null, 'integration/app_spec.coffee')
})
cy.contains('.all-tests', 'Running 1 spec')
cy.contains('.project-nav a', 'Settings').click()
cy.get('.settings').should('be.visible')
cy.contains('.project-nav a', 'Tests').click()
// the specs list renders again
cy.contains('.file-name', 'app_spec.coffee')
cy.contains('.all-tests', 'Running 1 spec')
})
})
})
describe('spec list updates', function () {
+12 -8
View File
@@ -28,6 +28,8 @@ const formRunButtonLabel = (areTestsAlreadyRunning, specType, specsN) => {
return label
}
// Note: this component can be mounted and unmounted
// if you need to persist the data through mounts, "save" it in the specsStore
@observer
class SpecsList extends Component {
constructor (props) {
@@ -167,7 +169,7 @@ class SpecsList extends Component {
const { project } = this.props
this.selectedSpec = spec
specsStore.setSelectedSpec(spec)
if (spec.relative === '__all') {
if (specsStore.filter) {
@@ -211,14 +213,16 @@ class SpecsList extends Component {
if (this._areTestsRunning()) {
// selected spec must be set
// only show the button matching current running spec type
if (spec.specType !== this.selectedSpec.specType) {
return <></>
}
if (specsStore.selectedSpec) {
// only show the button matching current running spec type
if (spec.specType !== specsStore.selectedSpec.specType) {
return <></>
}
if (this.selectedSpec.relative !== '__all') {
// we are only running 1 spec
buttonText = `${word} 1 spec`
if (specsStore.selectedSpec.relative !== '__all') {
// we are only running 1 spec
buttonText = `${word} 1 spec`
}
}
}
@@ -60,6 +60,7 @@ export class SpecsStore {
@observable error
@observable isLoading = false
@observable filter
@observable selectedSpec
@computed get specs () {
return this._tree(this._files)
@@ -135,6 +136,10 @@ export class SpecsStore {
this.filter = null
}
@action setSelectedSpec (spec) {
this.selectedSpec = spec
}
isChosen (spec) {
return pathsEqual(this.chosenSpecPath, formRelativePath(spec))
}
+39 -2
View File
@@ -5,12 +5,20 @@ const debug = require('debug')('cypress:electron')
const Promise = require('bluebird')
const minimist = require('minimist')
const inspector = require('inspector')
const execa = require('execa')
const paths = require('./paths')
const install = require('./install')
let fs = require('fs-extra')
fs = Promise.promisifyAll(fs)
/**
* If running as root on Linux, no-sandbox must be passed or Chrome will not start
*/
const isSandboxNeeded = () => {
return (os.platform() === 'linux') && (process.geteuid() === 0)
}
module.exports = {
installIfNeeded () {
return install.check()
@@ -26,6 +34,36 @@ module.exports = {
return install.getElectronVersion()
},
/**
* Returns the Node version bundled inside Electron.
*/
getElectronNodeVersion () {
debug('getting Electron Node version')
const args = []
if (isSandboxNeeded()) {
args.push('--no-sandbox')
}
// runs locally installed "electron" bin alias
const localScript = path.join(__dirname, 'print-node-version.js')
debug('local script that prints Node version %s', localScript)
args.push(localScript)
const options = {
preferLocal: true, // finds the "node_modules/.bin/electron"
timeout: 5000, // prevents hanging Electron if there is an error for some reason
}
debug('Running Electron with %o %o', args, options)
return execa('electron', args, options)
.then((result) => result.stdout)
},
icons () {
return install.icons()
},
@@ -73,8 +111,7 @@ module.exports = {
}).then(() => {
const execPath = paths.getPathToExec()
// if running as root, no-sandbox must be passed or Chrome will not start
if ((os.platform() === 'linux') && (process.geteuid() === 0)) {
if (isSandboxNeeded()) {
argv.unshift('--no-sandbox')
}
@@ -0,0 +1,3 @@
/* eslint-disable-next-line no-console */
console.log(process.version.replace('v', ''))
process.exit(0)
+1
View File
@@ -25,6 +25,7 @@
},
"devDependencies": {
"electron": "10.1.5",
"execa": "4.1.0",
"mocha": "3.5.3"
},
"files": [
@@ -294,3 +294,10 @@ You passed: nonono
The error was: Cannot read property 'split' of undefined
`
exports['INVALID_CONFIG_OPTION'] = `
\`test\` is not a valid configuration option,\`foo\` is not a valid configuration option
https://on.cypress.io/configuration
`
+18 -2
View File
@@ -14,8 +14,8 @@ const Promise = require('bluebird')
const debug = require('debug')('cypress:server:cypress')
const argsUtils = require('./util/args')
const warning = (code) => {
return require('./errors').warning(code)
const warning = (code, args) => {
return require('./errors').warning(code, args)
}
const exit = (code = 0) => {
@@ -27,6 +27,20 @@ const exit = (code = 0) => {
return process.exit(code)
}
const showWarningForInvalidConfig = (options) => {
const invalidConfigOptions = require('lodash').keys(options.config).reduce((invalid, option) => {
if (!require('./config').getConfigKeys().find((configKey) => configKey === option)) {
invalid.push(option)
}
return invalid
}, [])
if (invalidConfigOptions.length && options.invokedFromCli) {
return warning('INVALID_CONFIG_OPTION', invalidConfigOptions)
}
}
const exit0 = () => {
return exit(0)
}
@@ -115,6 +129,8 @@ module.exports = {
try {
options = argsUtils.toObject(argv)
showWarningForInvalidConfig(options)
} catch (argumentsError) {
debug('could not parse CLI arguments: %o', argv)
+6
View File
@@ -917,6 +917,12 @@ const getMsgByType = function (type, arg1 = {}, arg2, arg3) {
https://on.cypress.io/test-retries
`
case 'INVALID_CONFIG_OPTION':
return stripIndent`\
${arg1.map((arg) => `\`${arg}\` is not a valid configuration option`)}
https://on.cypress.io/configuration
`
default:
}
}
@@ -230,6 +230,48 @@ describe('lib/cypress', () => {
})
})
context('invalid config', function () {
beforeEach(function () {
this.win = {
on: sinon.stub(),
webContents: {
on: sinon.stub(),
},
}
sinon.stub(electron.app, 'on').withArgs('ready').yieldsAsync()
sinon.stub(Windows, 'open').resolves(this.win)
})
it('shows warning if config is not valid', function () {
return cypress.start(['--config=test=false', '--cwd=/foo/bar'])
.then(() => {
expect(errors.warning).to.be.calledWith('INVALID_CONFIG_OPTION')
expect(console.log).to.be.calledWithMatch('`test` is not a valid configuration option')
expect(console.log).to.be.calledWithMatch('https://on.cypress.io/configuration')
})
})
it('shows warning when multiple config are not valid', function () {
return cypress.start(['--config=test=false,foo=bar', '--cwd=/foo/bar'])
.then(() => {
expect(errors.warning).to.be.calledWith('INVALID_CONFIG_OPTION')
expect(console.log).to.be.calledWithMatch('`test` is not a valid configuration option')
expect(console.log).to.be.calledWithMatch('`foo` is not a valid configuration option')
expect(console.log).to.be.calledWithMatch('https://on.cypress.io/configuration')
snapshotConsoleLogs('INVALID_CONFIG_OPTION')
})
})
it('does not show warning if config is valid', function () {
return cypress.start(['--config=trashAssetsBeforeRuns=false'])
.then(() => {
expect(errors.warning).to.not.be.calledWith('INVALID_CONFIG_OPTION')
})
})
})
context('--get-key', () => {
it('writes out key and exits on success', function () {
return Promise.all([
+32 -12
View File
@@ -147,25 +147,45 @@ const buildCypressApp = function (platform, version, options = {}) {
return packages.npmInstallAll(pathToPackages)
}
/**
* Creates the package.json file that sits in the root of the output app
*/
const createRootPackage = function () {
log(`#createRootPackage ${platform} ${version}`)
return fs.outputJsonAsync(distDir('package.json'), {
name: 'cypress',
productName: 'Cypress',
description: rootPackage.description,
version,
main: 'index.js',
scripts: {},
env: 'production',
})
.then(() => {
const str = `\
const electronVersion = electron.getElectronVersion()
la(electronVersion, 'missing Electron version', electronVersion)
return electron.getElectronNodeVersion()
.then((electronNodeVersion) => {
la(electronNodeVersion, 'missing Electron Node version', electronNodeVersion)
const json = {
name: 'cypress',
productName: 'Cypress',
description: rootPackage.description,
version, // Cypress version
electronVersion,
electronNodeVersion,
main: 'index.js',
scripts: {},
env: 'production',
}
const outputFilename = distDir('package.json')
debug('writing to %s json %o', outputFilename, json)
return fs.outputJsonAsync(outputFilename, json)
.then(() => {
const str = `\
process.env.CYPRESS_INTERNAL_ENV = process.env.CYPRESS_INTERNAL_ENV || 'production'
require('./packages/server')\
`
return fs.outputFileAsync(distDir('index.js'), str)
return fs.outputFileAsync(distDir('index.js'), str)
})
})
}
+15
View File
@@ -14096,6 +14096,21 @@ execa@4.0.2:
signal-exit "^3.0.2"
strip-final-newline "^2.0.0"
execa@4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a"
integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==
dependencies:
cross-spawn "^7.0.0"
get-stream "^5.0.0"
human-signals "^1.1.1"
is-stream "^2.0.0"
merge-stream "^2.0.0"
npm-run-path "^4.0.0"
onetime "^5.1.0"
signal-exit "^3.0.2"
strip-final-newline "^2.0.0"
execa@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/execa/-/execa-0.2.2.tgz#e2ead472c2c31aad6f73f1ac956eef45e12320cb"