mirror of
https://github.com/cypress-io/cypress.git
synced 2025-12-30 11:09:49 -06:00
cli: tests around install including snapshots, woo!
This commit is contained in:
90
cli/__snapshots__/install_spec.js
Normal file
90
cli/__snapshots__/install_spec.js
Normal 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 [32m✔[39m Downloaded Cypress
|
||||
[32m✔[39m Unzipped Cypress
|
||||
[32m✔[39m 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 [32m✔[39m Downloaded Cypress
|
||||
[32m✔[39m Unzipped Cypress
|
||||
[32m✔[39m 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 [32m✔[39m Downloaded Cypress
|
||||
[32m✔[39m Unzipped Cypress
|
||||
[32m✔[39m 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 [32m✔[39m Downloaded Cypress
|
||||
[32m✔[39m Unzipped Cypress
|
||||
[32m✔[39m 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 [32m✔[39m Downloaded Cypress
|
||||
[32m✔[39m Unzipped Cypress
|
||||
[32m✔[39m 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 [32m✔[39m Downloaded Cypress
|
||||
[32m✔[39m Unzipped Cypress
|
||||
[32m✔[39m 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
|
||||
`
|
||||
|
||||
@@ -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()}
|
||||
`)
|
||||
}
|
||||
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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())
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
@@ -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 () {
|
||||
|
||||
28
cli/test/support/stdout.js
Normal file
28
cli/test/support/stdout.js
Normal 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
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user