mirror of
https://github.com/cypress-io/cypress.git
synced 2026-05-04 22:10:40 -05:00
Merge branch 'develop' into v6.0-release
This commit is contained in:
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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'] = `
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -281,7 +281,7 @@ const start = (options = {}) => {
|
||||
})
|
||||
.then(() => {
|
||||
return Promise.all([
|
||||
state.getBinaryPkgVersionAsync(binaryDir),
|
||||
state.getBinaryPkgAsync(binaryDir).then(state.getBinaryPkgVersion),
|
||||
getVersionSpecifier(),
|
||||
])
|
||||
})
|
||||
|
||||
+15
-3
@@ -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,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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(() => {
|
||||
|
||||
@@ -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',
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -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'
|
||||
|
||||
|
||||
@@ -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' })
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -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 () {
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
`
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
@@ -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)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user