cli: tests around install including snapshots, woo!

This commit is contained in:
Brian Mann
2017-09-04 01:47:21 -04:00
parent 0dbda32419
commit 9a38bca34c
8 changed files with 268 additions and 87 deletions

View File

@@ -0,0 +1,90 @@
exports['install .start override version warns when specifying cypress version in env 1'] = `Forcing a binary version different than the default.
The CLI expected to install version: 1.2.3
Instead we will install version: 0.12.1
Note: there is no guarantee these versions will work properly together.
Installing Cypress (version: 0.12.1)
[?25l ✔ Downloaded Cypress
✔ Unzipped Cypress
✔ Finished Installation /path/to/binary/dir/
[?25h
You can now open Cypress by running: node_modules/.bin/cypress open
https://on.cypress.io/installing-cypress
`
exports['install .start when getting installed version fails logs message and starts download 1'] = `Installing Cypress (version: 1.2.3)
[?25l ✔ Downloaded Cypress
✔ Unzipped Cypress
✔ Finished Installation /path/to/binary/dir/
[?25h
You can now open Cypress by running: node_modules/.bin/cypress open
https://on.cypress.io/installing-cypress
`
exports['install .start when getting installed version does not match needed version logs message and starts download 1'] = `Installed version (x.x.x) does not match needed version (1.2.3).
Installing Cypress (version: 1.2.3)
[?25l ✔ Downloaded Cypress
✔ Unzipped Cypress
✔ Finished Installation /path/to/binary/dir/
[?25h
You can now open Cypress by running: node_modules/.bin/cypress open
https://on.cypress.io/installing-cypress
`
exports['install .start when there is no install version logs message and starts download 1'] = `Installing Cypress (version: 1.2.3)
[?25l ✔ Downloaded Cypress
✔ Unzipped Cypress
✔ Finished Installation /path/to/binary/dir/
[?25h
You can now open Cypress by running: node_modules/.bin/cypress open
https://on.cypress.io/installing-cypress
`
exports['install .start with force: true logs message and starts download 1'] = `Installing Cypress (version: 1.2.3)
[?25l ✔ Downloaded Cypress
✔ Unzipped Cypress
✔ Finished Installation /path/to/binary/dir/
[?25h
You can now open Cypress by running: node_modules/.bin/cypress open
https://on.cypress.io/installing-cypress
`
exports['install .start when version is already installed logs noop message 1'] = `Cypress 1.2.3 is already installed. Skipping installation.
Pass the --force option if you'd like to reinstall anyway.
`
exports['install .start as a global install logs global warning and download 1'] = `Installed version (x.x.x) does not match needed version (1.2.3).
Installing Cypress (version: 1.2.3)
[?25l ✔ Downloaded Cypress
✔ Unzipped Cypress
✔ Finished Installation /path/to/binary/dir/
[?25h
It looks like you've installed Cypress globally.
This will work, but it's not recommended.
The recommended way to install Cypress is as a devDependency per project.
You should probably run these commands:
- npm uninstall -g cypress
- npm install --save-dev cypress
`

View File

@@ -11,8 +11,6 @@ const issuesUrl = 'https://github.com/cypress-io/cypress/issues'
const docsUrl = 'https://on.cypress.io'
const requiredDependenciesUrl = `${docsUrl}/required-dependencies`
const pkgVersion = util.pkgVersion()
// common errors Cypress application can encounter
const failedDownload = {
description: 'The Cypress App could not be downloaded.',
@@ -40,17 +38,16 @@ const missingXvfb = {
solution: stripIndent`
Install XVFB and run Cypress again.
Our CI documentation provides more information how to configure dependencies
`,
footer: stripIndent`
Read our doc on CI dependencies for more information:
Read our documentation on dependencies for more information:
${requiredDependenciesUrl}
If you using Docker, we provide containers with all required dependencies installed.
`,
}
const missingDependency = {
description: 'We could not run Cypress.',
description: 'Cypress failed to start.',
// this message is too Linux specific
solution: stripIndent`
This is usually caused by a missing library or dependency.
@@ -58,6 +55,8 @@ const missingDependency = {
The error below should indicate which dependency is missing.
${requiredDependenciesUrl}
If you using Docker, we provide containers with all required dependencies installed.
`,
}
@@ -95,7 +94,7 @@ function getPlatformInfo () {
return getOsVersion()
.then((version) => stripIndent`
Platform: ${os.platform()} (${version})
Cypress Version: ${pkgVersion}
Cypress Version: ${util.pkgVersion()}
`)
}

View File

@@ -5,12 +5,12 @@ let logs = []
const error = (...messages) => {
logs.push(messages.join(' '))
console.error(chalk.red(...messages)) // eslint-disable-line no-console
console.log(chalk.red(...messages)) // eslint-disable-line no-console
}
const warn = (...messages) => {
logs.push(messages.join(' '))
console.error(chalk.yellow(...messages)) // eslint-disable-line no-console
console.log(chalk.yellow(...messages)) // eslint-disable-line no-console
}
const log = (...messages) => {

View File

@@ -12,8 +12,6 @@ const info = require('./info')
const unzip = require('./unzip')
const logger = require('../logger')
const hasSomethingToSay = (err) => err && err.message
const alreadyInstalledMsg = (installedVersion, needVersion) => {
logger.log(chalk.yellow(stripIndent`
Cypress ${chalk.cyan(needVersion)} is already installed. Skipping installation.
@@ -32,7 +30,7 @@ const displayCompletionMsg = () => {
// check here to see if we are globally installed
if (util.isInstalledGlobally()) {
// if we are display a warning
logger.log(chalk.yellow(stripIndent`
logger.warn(stripIndent`
It looks like you\'ve installed Cypress globally.
This will work, but it'\s not recommended.
@@ -43,7 +41,7 @@ const displayCompletionMsg = () => {
- ${chalk.cyan('npm uninstall -g cypress')}
- ${chalk.cyan('npm install --save-dev cypress')}
`))
`)
return
}
@@ -173,35 +171,35 @@ const start = (options = {}) => {
}
return info.getInstalledVersion()
.catch(() => {
throw new Error('Cypress executable was not found.')
})
.catchReturn(null)
.then((installedVersion) => {
debug('installed version is', installedVersion, 'version needed is', needVersion)
if (options.force) {
return info.clearVersionState()
.then(() => {
throw new Error('')
})
} else if (installedVersion === needVersion) {
// our version matches, tell the user this is a noop
return alreadyInstalledMsg(installedVersion, needVersion)
} else if (!installedVersion) {
// logger.log('Could not find installed Cypress')
return info.clearVersionState()
.then(() => {
throw new Error('')
})
} else {
throw new Error(`Installed version (${installedVersion}) does not match needed version (${needVersion}).`)
}
if (installedVersion === needVersion) {
// our version matches, tell the user this is a noop
alreadyInstalledMsg(installedVersion, needVersion)
return false
}
if (!installedVersion) {
return info.clearVersionState()
}
logger.warn(stripIndent`
Installed version (${chalk.cyan(installedVersion)}) does not match needed version (${chalk.cyan(needVersion)}).
`)
logger.log()
})
.catch((err) => {
if (hasSomethingToSay(err)) {
logger.log(err.message)
.then((ret) => {
// noop if we've been told not to download
if (ret === false) {
return
}
// TODO: what to do about this? let's just not support it

View File

@@ -11,7 +11,7 @@ const run = require(`${lib}/exec/run`)
const cypress = require(`${lib}/cypress`)
describe('cypress', function () {
context('#open', function () {
context('.open', function () {
it('calls open#start, passing in options', function () {
this.sandbox.stub(open, 'start').resolves()
cypress.open({ foo: 'foo' })
@@ -19,7 +19,7 @@ describe('cypress', function () {
})
})
context('#run', function () {
context('.run', function () {
beforeEach(function () {
this.outputPath = path.join(os.tmpdir(), 'cypress/monorepo/cypress_spec/output.json')
this.sandbox.stub(tmp, 'fileAsync').resolves(this.outputPath)

View File

@@ -1,6 +1,10 @@
require('../../spec_helper')
const chalk = require('chalk')
const Promise = require('bluebird')
const snapshot = require('snap-shot-it')
const stdout = require('../../support/stdout')
const fs = require(`${lib}/fs`)
const download = require(`${lib}/tasks/download`)
@@ -10,23 +14,34 @@ const unzip = require(`${lib}/tasks/unzip`)
const logger = require(`${lib}/logger`)
const util = require(`${lib}/util`)
const packageVersion = util.pkgVersion()
const packageVersion = '1.2.3'
const downloadDestination = 'path/to/cypress.zip'
describe('install', function () {
beforeEach(() => {
beforeEach(function () {
this.stdout = stdout.capture()
// allow simpler log message comparison without
// chalk's terminal control strings
chalk.enabled = false
})
afterEach(() => {
stdout.restore()
chalk.enabled = true
})
context('.start', function () {
beforeEach(function () {
this.sandbox.stub(logger, 'log')
this.sandbox.stub(download, 'start').resolves()
logger.reset()
this.sandbox.stub(util, 'pkgVersion').returns(packageVersion)
this.sandbox.stub(download, 'start').resolves(downloadDestination)
this.sandbox.stub(unzip, 'start').resolves()
this.sandbox.stub(Promise, 'delay').resolves()
this.sandbox.stub(fs, 'removeAsync').resolves()
this.sandbox.stub(info, 'getPathToUserExecutableDir').returns('/path/to/binary/dir/')
this.sandbox.stub(info, 'getInstalledVersion').resolves()
this.sandbox.stub(info, 'writeInstalledVersion').resolves()
this.sandbox.stub(info, 'clearVersionState').resolves()
@@ -34,28 +49,30 @@ describe('install', function () {
describe('override version', function () {
afterEach(function () {
delete process.env.CYPRESS_VERSION
delete process.env.CYPRESS_BINARY_VERSION
})
it('can specify cypress version in env', function () {
it('warns when specifying cypress version in env', function () {
const version = '0.12.1'
process.env.CYPRESS_VERSION = version
process.env.CYPRESS_BINARY_VERSION = version
return install.install()
.then(() => {
const msg = `Forcing CYPRESS_VERSION ${version}`
expect(logger.log.calledWith(msg)).to.be.true
expect(download.start).to.be.calledWith({
displayOpen: false,
version,
cypressVersion: version,
})
return install.start()
.then(() => {
expect(download.start).to.be.calledWithMatch({
version,
})
expect(unzip.start).to.be.calledWithMatch({
version,
})
snapshot(this.stdout.toString())
})
})
it('can install local binary zip file without download', function () {
it.skip('can install local binary zip file without download', function () {
const version = '/tmp/local/file.zip'
process.env.CYPRESS_VERSION = version
process.env.CYPRESS_BINARY_VERSION = version
this.sandbox.stub(fs, 'statAsync').withArgs(version).resolves()
this.sandbox.stub(unzip, 'start').resolves()
@@ -74,74 +91,122 @@ describe('install', function () {
describe('when version is already installed', function () {
beforeEach(function () {
info.getInstalledVersion.resolves(packageVersion)
return install.start()
})
it('logs message', function () {
const msg = `Cypress ${packageVersion} already installed.`
expect(logger.log.calledWith(msg)).to.be.true
})
it('does not download', function () {
it('logs noop message', function () {
expect(download.start).not.to.be.called
snapshot(this.stdout.toString())
})
})
describe('when getting installed version fails', function () {
beforeEach(function () {
info.getInstalledVersion.rejects(new Error('no'))
return install.start()
})
it('logs message', function () {
expect(logger.log.calledWith('Cypress executable was not found.')).to.be.true
expect(logger.log.calledWith(`Installing Cypress (version: ${packageVersion}).`)).to.be.true
})
it('downloads', function () {
expect(download.start).to.be.calledWith({
displayOpen: false,
cypressVersion: packageVersion,
it('logs message and starts download', function () {
expect(download.start).to.be.calledWithMatch({
version: packageVersion,
})
expect(unzip.start).to.be.calledWithMatch({
version: packageVersion,
})
snapshot(this.stdout.toString())
})
})
describe('when there is no install version', function () {
beforeEach(function () {
info.getInstalledVersion.resolves(null)
return install.start()
})
it('logs message and starts download', function () {
expect(info.clearVersionState).to.be.called
expect(download.start).to.be.calledWithMatch({
version: packageVersion,
})
expect(unzip.start).to.be.calledWithMatch({
version: packageVersion,
})
snapshot(this.stdout.toString())
})
})
describe('when getting installed version does not match needed version', function () {
beforeEach(function () {
info.getInstalledVersion.resolves('x.x.x')
return install.start()
})
it('logs message', function () {
const versionMessage = `Installed version (x.x.x) does not match needed version (${packageVersion}).`
expect(logger.log.calledWith(versionMessage)).to.be.true
const installMessage = `Installing Cypress (version: ${packageVersion}).`
expect(logger.log.calledWith(installMessage)).to.be.true
})
it('downloads', function () {
expect(download.start).to.be.calledWith({
displayOpen: false,
cypressVersion: packageVersion,
it('logs message and starts download', function () {
expect(download.start).to.be.calledWithMatch({
version: packageVersion,
})
expect(unzip.start).to.be.calledWithMatch({
version: packageVersion,
})
snapshot(this.stdout.toString())
})
})
describe('with force: true', function () {
beforeEach(function () {
info.getInstalledVersion.resolves(packageVersion)
return install.start({ force: true })
})
it('clears version state', function () {
it('logs message and starts download', function () {
expect(info.clearVersionState).to.be.called
})
it('forces download even if version matches', function () {
expect(download.start).to.be.called
expect(download.start).to.be.calledWithMatch({
version: packageVersion,
})
expect(unzip.start).to.be.calledWithMatch({
version: packageVersion,
})
snapshot(this.stdout.toString())
})
})
describe('as a global install', function () {
beforeEach(function () {
this.sandbox.stub(util, 'isInstalledGlobally').returns(true)
info.getInstalledVersion.resolves('x.x.x')
return install.start()
})
it('logs global warning and download', function () {
expect(download.start).to.be.calledWithMatch({
version: packageVersion,
})
expect(unzip.start).to.be.calledWithMatch({
version: packageVersion,
})
snapshot(this.stdout.toString())
})
})
})
})

View File

@@ -1,5 +1,6 @@
const path = require('path')
const sinon = require('sinon')
const Promise = require('bluebird')
global.expect = require('chai').expect
global.lib = path.join(__dirname, '..', 'lib')
@@ -8,7 +9,7 @@ require('chai')
.use(require('@cypress/sinon-chai'))
beforeEach(function () {
this.sandbox = sinon.sandbox.create()
this.sandbox = sinon.sandbox.create().usingPromise(Promise)
})
afterEach(function () {

View File

@@ -0,0 +1,28 @@
const _write = process.stdout.write
module.exports = {
capture () {
const logs = []
const write = process.stdout.write
process.stdout.write = function (str) {
logs.push(str)
/* eslint-disable prefer-rest-params */
write.apply(this, arguments)
}
return {
data: logs,
toString: () => {
return logs.join('')
},
}
},
restore () {
process.stdout.write = _write
},
}