You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

129 lines
3.8 KiB

'use strict';
var _ = require('lodash');
var os = require('os');
var cp = require('child_process');
var tty = require('tty');
var path = require('path');
var Promise = require('bluebird');
var debug = require('debug')('cypress:cli');
var util = require('../util');
var info = require('../tasks/info');
var xvfb = require('./xvfb');
var _require = require('../errors'),
throwFormErrorText = _require.throwFormErrorText,
errors = _require.errors;
var isXlibOrLibudevRe = /^(Xlib|libudev)/;
function needsStderrPipe(needsXvfb) {
return needsXvfb && os.platform() === 'linux';
}
function getStdio(needsXvfb) {
// https://github.com/cypress-io/cypress/issues/921
if (needsStderrPipe(needsXvfb)) {
// returning pipe here so we can massage stderr
// and remove garbage from Xlib and libuv
// due to starting the XVFB process on linux
return ['inherit', 'inherit', 'pipe'];
}
return 'inherit';
}
module.exports = {
start: function start(args) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var needsXvfb = xvfb.isNeeded();
debug('needs XVFB?', needsXvfb);
// always push cwd into the args
args = [].concat(args, '--cwd', process.cwd());
_.defaults(options, {
detached: false,
stdio: getStdio(needsXvfb)
});
var spawn = function spawn() {
return new Promise(function (resolve, reject) {
var cypressPath = info.getPathToExecutable();
if (options.dev) {
// if we're in dev then reset
// the launch cmd to be 'npm run dev'
cypressPath = 'node';
args.unshift(path.resolve(__dirname, '..', '..', '..', 'scripts', 'start.js'));
}
debug('spawning Cypress %s', cypressPath);
debug('spawn args %j', args, options);
// strip dev out of child process options
options = _.omit(options, 'dev');
// when running in electron in windows
// it never supports color but we're
// going to force it anyway as long
// as our parent cli process can support
// colors!
//
// also when we are in linux and using the 'pipe'
// option our process.stderr.isTTY will not be true
// which ends up disabling the colors =(
if (util.supportsColor()) {
process.env.FORCE_COLOR = 1;
process.env.DEBUG_COLORS = 1;
process.env.MOCHA_COLORS = 1;
}
// if we needed to pipe stderr and we're currently
// a tty on stderr
if (needsStderrPipe(needsXvfb) && tty.isatty(2)) {
// then force stderr tty
//
// this is necessary because we want our child
// electron browser to behave _THE SAME WAY_ as
// if we aren't using pipe. pipe is necessary only
// to filter out garbage on stderr -____________-
process.env.FORCE_STDERR_TTY = 1;
}
var child = cp.spawn(cypressPath, args, options);
child.on('close', resolve);
child.on('error', reject);
// if this is defined then we are manually piping for linux
// to filter out the garbage
child.stderr && child.stderr.on('data', function (data) {
// bail if this is a line from xlib or libudev
if (isXlibOrLibudevRe.test(data.toString())) {
return;
}
// else pass it along!
process.stderr.write(data);
});
if (options.detached) {
child.unref();
}
});
};
var userFriendlySpawn = function userFriendlySpawn() {
return spawn().catch(throwFormErrorText(errors.unexpected));
};
if (needsXvfb) {
return xvfb.start().then(userFriendlySpawn).finally(xvfb.stop);
} else {
return userFriendlySpawn();
}
}
};