Merge branch 'master' of github.com:cypress-io/cypress-monorepo

This commit is contained in:
Chris Breiding
2017-06-22 14:02:45 -04:00
17 changed files with 111 additions and 54 deletions
+1 -1
View File
@@ -25,7 +25,7 @@ This will install this repo's direct dependencies as well as the dependencies fo
Then, build all the packages and start the app:
```bash
npm run all build-dev
npm run all build
npm start
```
+3 -1
View File
@@ -50,7 +50,9 @@ module.exports = {
.option('-e, --env <env>', text('env'))
.option('-c, --config <config>', text('config'))
.option('-b, --browser <browser name>', text('browser'))
.action((opts) => require('./exec/run').start(parseOpts(opts)))
.action((opts) =>
require('./exec/run').start(parseOpts(opts)).then(process.exit)
)
program
.command('open')
+12 -3
View File
@@ -18,9 +18,18 @@ module.exports = {
options.outputPath = outputPath
return run.start(options)
.then(() => {
return fs.readJsonAsync(outputPath)
})
.then((failedTests) =>
fs.readJsonAsync(outputPath, { throws: false })
.then((output) => {
if (!output) {
return {
failures: failedTests,
message: 'Could not find Cypress test run results',
}
}
return output
})
)
})
},
}
+1 -1
View File
@@ -7,7 +7,7 @@ const Promise = require('bluebird')
const request = require('request')
const url = require('url')
const debug = require('debug')('cypress:cli')
const { formErrorText, errors } = require('./errors')
const { formErrorText, errors } = require('../errors')
const { stripIndent } = require('common-tags')
const R = require('ramda')
const pkg = require('../../package.json')
+1 -1
View File
@@ -4,7 +4,7 @@ const os = require('os')
const Promise = require('bluebird')
const readline = require('readline')
const yauzl = require('yauzl')
const { formErrorText, errors } = require('./errors')
const { formErrorText, errors } = require('../errors')
const utils = require('./utils')
const fs = Promise.promisifyAll(require('fs-extra'))
+1 -1
View File
@@ -11,7 +11,7 @@ const { stripIndent } = require('common-tags')
const ProgressBar = require('progress')
const xvfb = require('../exec/xvfb')
const { formErrorText, errors } = require('./errors')
const { formErrorText, errors } = require('../errors')
const packagePath = path.join(__dirname, '..', '..', 'package.json')
const packageVersion = require(packagePath).version
@@ -120,9 +120,18 @@ function formErrorText (info, error) {
`)
}
const raise = (text) => {
throw new Error(text)
}
const throwDetailedError = (info) => (error) =>
formErrorText(info, error)
.then(raise)
module.exports = {
formError,
formErrorText,
throwDetailedError,
errors: {
missingXvfb,
missingApp,
+4 -3
View File
@@ -1,5 +1,5 @@
const _ = require('lodash')
const debug = require('debug')('cypress:cli')
const downloadUtils = require('../download/utils')
const spawn = require('./spawn')
const path = require('path')
@@ -76,11 +76,13 @@ const processRunOptions = (options = {}) => {
const run = (options) => () => {
const args = processRunOptions(options)
debug('run to spawn.start args %j', args)
return spawn.start(args)
}
module.exports = {
processRunOptions,
// resolves with the number of failed tests
start (options = {}) {
_.defaults(options, {
key: null,
@@ -90,7 +92,6 @@ module.exports = {
project: process.cwd(),
})
return downloadUtils.verify()
.then(run(options))
return downloadUtils.verify().then(run(options))
},
}
+11 -25
View File
@@ -5,20 +5,12 @@ const debug = require('debug')('cypress:cli')
const downloadUtils = require('../download/utils')
const xvfb = require('./xvfb')
const { formErrorText, errors } = require('../download/errors')
const logAndFail = (info) => (err) => {
const text = formErrorText(info, err)
console.log(text) // eslint-disable-line no-console
process.exit(1)
}
const { throwDetailedError, errors } = require('../errors')
module.exports = {
start (args, options = {}) {
args = [].concat(args)
const needsXvfb = xvfb.isNeeded()
_.defaults(options, {
verify: false,
detached: false,
@@ -26,38 +18,32 @@ module.exports = {
})
const spawn = () => {
return new Promise((resolve) => {
return new Promise((resolve, reject) => {
const cypressPath = downloadUtils.getPathToExecutable()
debug('spawning Cypress %s', cypressPath)
debug('args %j', args)
debug('some of the options %j', _.pick(options, ['verify', 'detached']))
const child = cp.spawn(cypressPath, args, options)
if (needsXvfb) {
//// make sure we close down xvfb
//// when our spawned process exits
child.on('close', xvfb.stop)
}
//// when our spawned process exits
//// make sure we kill our own process
//// with its exit code (to bubble up errors)
child.on('exit', process.exit)
child.on('exit', resolve)
child.on('error', reject)
if (options.detached) {
child.unref()
}
resolve(child)
})
}
const userFriendlySpawn = () =>
spawn().catch(throwDetailedError(errors.unexpected))
const needsXvfb = xvfb.isNeeded()
if (needsXvfb) {
return xvfb.start()
.then(spawn)
.catch(logAndFail(errors.missingXvfb))
.then(userFriendlySpawn)
.finally(xvfb.stop)
} else {
return spawn()
return userFriendlySpawn()
}
},
}
+4
View File
@@ -3,12 +3,16 @@ const Promise = require('bluebird')
const Xvfb = require('@cypress/xvfb')
const R = require('ramda')
const debug = require('debug')('cypress:cli')
const { throwDetailedError, errors } = require('../errors')
const xvfb = Promise.promisifyAll(new Xvfb({ silent: true }))
module.exports = {
_xvfb: xvfb, // expose for testing
start () {
return xvfb.startAsync()
.catch(throwDetailedError(errors.missingXvfb))
},
stop () {
+12 -1
View File
@@ -1,5 +1,6 @@
require('./spec_helper')
const _ = require('lodash')
const cli = require('../lib/cli')
const download = require('../lib/download')
const downloadUtils = require('../lib/download/utils')
@@ -8,11 +9,21 @@ const open = require('../lib/exec/open')
describe('cli', function () {
beforeEach(function () {
this.sandbox.stub(process, 'exit')
this.exec = (args) => cli.init().parse(`node test ${args}`.split(' '))
})
it('exits when done', function (done) {
this.sandbox.stub(run, 'start').resolves()
this.exec('run --port 7878')
_.defer(() => {
expect(process.exit).to.be.calledOnce
done()
})
})
it('run calls run#start with options', function () {
this.sandbox.stub(run, 'start')
this.sandbox.stub(run, 'start').resolves()
this.exec('run --port 7878')
expect(run.start).to.be.calledWith({ port: '7878' })
})
+1 -1
View File
@@ -1,7 +1,7 @@
require('../spec_helper')
const os = require('os')
const { errors, formError, formErrorText } = require('../../lib/download/errors')
const { errors, formError, formErrorText } = require('../../lib/errors')
const snapshot = require('snap-shot')
const { omit } = require('ramda')
+1 -2
View File
@@ -40,8 +40,7 @@ describe('exec run', function () {
context('cli interface', function () {
beforeEach(function () {
this.sandbox.stub(run, 'start')
this.sandbox.stub(run, 'start').resolves()
this.parse = (args) => cli.init().parse(`node test ${args}`.split(' '))
})
+28 -9
View File
@@ -1,7 +1,5 @@
require('../spec_helper')
const _ = require('lodash')
const EE = require('events').EventEmitter
const cp = require('child_process')
const downloadUtils = require('../../lib/download/utils')
@@ -11,8 +9,9 @@ const spawn = require('../../lib/exec/spawn')
describe('exec spawn', function () {
beforeEach(function () {
this.sandbox.stub(process, 'exit')
this.spawnedProcess = _.extend(new EE(), {
unref: this.sandbox.stub(),
this.spawnedProcess = this.sandbox.stub({
on: () => {},
unref: () => {},
})
this.sandbox.stub(cp, 'spawn').returns(this.spawnedProcess)
this.sandbox.stub(xvfb, 'start').resolves()
@@ -23,12 +22,14 @@ describe('exec spawn', function () {
context('#spawn', function () {
it('passes args + options to spawn', function () {
this.spawnedProcess.on.withArgs('exit').yieldsAsync(0)
return spawn.start('--foo', { foo: 'bar' }).then(() => {
expect(cp.spawn).to.be.calledWithMatch('/path/to/cypress', ['--foo'], { foo: 'bar' })
})
})
it('starts xvfb when needed', function () {
this.spawnedProcess.on.withArgs('exit').yieldsAsync(0)
return spawn.start('--foo').then(() => {
expect(xvfb.start).to.be.calledOnce
})
@@ -37,32 +38,50 @@ describe('exec spawn', function () {
it('does not start xvfb when its not needed', function () {
xvfb.isNeeded.returns(false)
this.spawnedProcess.on.withArgs('exit').yieldsAsync(0)
return spawn.start('--foo').then(() => {
expect(xvfb.start).not.to.be.called
})
})
it('stops xvfb when spawn closes', function () {
this.spawnedProcess.on.withArgs('exit').yieldsAsync(0)
this.spawnedProcess.on.withArgs('close').yields()
return spawn.start('--foo').then(() => {
this.spawnedProcess.emit('close')
expect(xvfb.stop).to.be.calledOnce
})
})
it('exits with spawned exit code', function () {
return spawn.start('--foo').then(() => {
this.spawnedProcess.emit('exit', 10)
expect(process.exit).to.be.calledWith(10)
it('resolves with spawned exit code in the message', function () {
this.spawnedProcess.on.withArgs('exit').yieldsAsync(10)
return spawn.start('--foo')
.then((code) => {
expect(code).to.equal(10)
})
})
it('rejects with error from spawn', function () {
const msg = 'the error message'
this.spawnedProcess.on.withArgs('error').yieldsAsync(new Error(msg))
return spawn.start('--foo')
.then(() => {
throw new Error('should have hit error handler but did not')
}, (e) => {
expect(e.message).to.include(msg)
})
})
it('unrefs if options.detached is true', function () {
this.spawnedProcess.on.withArgs('exit').yieldsAsync(0)
return spawn.start(null, { detached: true }).then(() => {
expect(this.spawnedProcess.unref).to.be.calledOnce
})
})
it('does not unref by default', function () {
this.spawnedProcess.on.withArgs('exit').yieldsAsync(0)
return spawn.start().then(() => {
expect(this.spawnedProcess.unref).not.to.be.called
})
+19 -2
View File
@@ -1,10 +1,27 @@
require('../spec_helper')
const os = require('os')
const xvfb = require('../../lib/exec/xvfb')
const os = require('os')
describe('exec xvfb', function () {
context('#start', function () {
it('passes', function () {
this.sandbox.stub(xvfb._xvfb, 'startAsync').resolves()
return xvfb.start()
})
it('fails with error message', function () {
const message = 'nope'
this.sandbox.stub(xvfb._xvfb, 'startAsync').rejects(new Error(message))
return xvfb.start()
.then(() => {
throw new Error('Should have thrown an error')
}, (err) => {
expect(err.message).to.include(message)
})
})
})
context('#isNeeded', function () {
afterEach(() => delete process.env.DISPLAY)
@@ -61,7 +61,7 @@ describe "Update Banner", ->
it "modal has info about downloading new version", ->
cy.get(".modal").contains("Download the new version")
it.only "opens download link when Download is clicked", ->
it "opens download link when Download is clicked", ->
cy.contains("Download the new version").click().then =>
expect(@ipc.externalOpen).to.be.calledWith("https://download.cypress.io/desktop?os=linux64")
+2 -2
View File
@@ -30,7 +30,7 @@ npm run lint
#### For development
```bash
npm run build-dev
npm run build
```
#### For production
@@ -42,7 +42,7 @@ npm run build-prod
### Watching
```bash
npm run watch-dev
npm run watch
```
### Testing