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.
 
 

228 lines
7.8 KiB

'use strict';
var _templateObject = _taggedTemplateLiteral(['\n Cypress executable not found at: ', '\n '], ['\n Cypress executable not found at: ', '\n ']),
_templateObject2 = _taggedTemplateLiteral(['\n Smoke test returned wrong code.\n\n Command was: ', '\n\n Returned: ', '\n '], ['\n Smoke test returned wrong code.\n\n Command was: ', '\n\n Returned: ', '\n ']),
_templateObject3 = _taggedTemplateLiteral(['\n Installed version ', ' does not match the expected package version ', '\n\n Note: there is no guarantee these versions will work properly together.\n '], ['\n Installed version ', ' does not match the expected package version ', '\n\n Note: there is no guarantee these versions will work properly together.\n ']);
function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
var _ = require('lodash');
var cp = require('child_process');
var chalk = require('chalk');
var Listr = require('listr');
var debug = require('debug')('cypress:cli');
var verbose = require('@cypress/listr-verbose-renderer');
var _require = require('common-tags'),
stripIndent = _require.stripIndent;
var Promise = require('bluebird');
var _require2 = require('../errors'),
throwFormErrorText = _require2.throwFormErrorText,
errors = _require2.errors;
var fs = require('../fs');
var util = require('../util');
var logger = require('../logger');
var xvfb = require('../exec/xvfb');
var info = require('./info');
var differentFrom = function differentFrom(a, b) {
return a !== b;
};
var verificationError = function verificationError(message) {
return _.extend(new Error(''), { name: '', message: message, isVerificationError: true });
};
var xvfbError = function xvfbError(message) {
return _.extend(new Error(''), { name: '', message: message, isXvfbError: true });
};
var checkIfNotInstalledOrMissingExecutable = function checkIfNotInstalledOrMissingExecutable(installedVersion, executable) {
debug('checking if executable exists', executable);
return fs.statAsync(executable).then(function () {
// after verifying its physically accessible
// we can now check that its installed in info.json
if (!installedVersion) {
throw new Error();
}
}).catch(function () {
// bail if we don't have an installed version
// because its physically missing or its
// not in info.json
return throwFormErrorText(errors.missingApp)(stripIndent(_templateObject, chalk.cyan(executable)));
});
};
var writeVerifiedVersion = function writeVerifiedVersion(verifiedVersion) {
debug('writing verified version string "%s"', verifiedVersion);
return info.ensureFileInfoContents().then(function (contents) {
return info.writeInfoFileContents(_.extend(contents, { verifiedVersion: verifiedVersion }));
});
};
var runSmokeTest = function runSmokeTest() {
debug('running smoke test');
var stderr = '';
var stdout = '';
var cypressExecPath = info.getPathToExecutable();
debug('using Cypress executable %s', cypressExecPath);
// TODO switch to execa for this?
var spawn = function spawn() {
return new Promise(function (resolve, reject) {
var random = _.random(0, 1000);
var args = ['--smoke-test', '--ping=' + random];
var smokeTestCommand = cypressExecPath + ' ' + args.join(' ');
debug('smoke test command:', smokeTestCommand);
var child = cp.spawn(cypressExecPath, args);
child.stderr.on('data', function (data) {
stderr += data.toString();
});
child.stdout.on('data', function (data) {
stdout += data.toString();
});
child.on('error', reject);
child.on('close', function (code) {
if (code === 0) {
var smokeTestReturned = stdout.trim();
debug('smoke test output "%s"', smokeTestReturned);
if (!util.stdoutLineMatches(String(random), smokeTestReturned)) {
return reject(new Error(stripIndent(_templateObject2, smokeTestCommand, smokeTestReturned)));
}
return resolve();
}
reject(verificationError(stderr));
});
});
};
var onXvfbError = function onXvfbError(err) {
debug('caught xvfb error %s', err.message);
throw xvfbError('Caught error trying to run XVFB: "' + err.message + '"');
};
var needsXvfb = xvfb.isNeeded();
debug('needs XVFB?', needsXvfb);
if (needsXvfb) {
return xvfb.start().catch(onXvfbError).then(spawn).finally(function () {
return xvfb.stop().catch(onXvfbError);
});
} else {
return spawn();
}
};
function testBinary(version) {
debug('running binary verification check', version);
var dir = info.getPathToUserExecutableDir();
// let the user know what version of cypress we're downloading!
logger.log(chalk.yellow('It looks like this is your first time using Cypress: ' + chalk.cyan(version)));
logger.log();
// if we are running in CI then use
// the verbose renderer else use
// the default
var rendererOptions = {
renderer: util.isCi() ? verbose : 'default'
};
var tasks = new Listr([{
title: util.titleize('Verifying Cypress can run', chalk.gray(dir)),
task: function task(ctx, _task) {
// clear out the verified version
return writeVerifiedVersion(null).then(function () {
return Promise.all([runSmokeTest(), Promise.delay(1500)] // good user experience
);
}).then(function () {
return writeVerifiedVersion(version);
}).then(function () {
util.setTaskTitle(_task, util.titleize(chalk.green('Verified Cypress!'), chalk.gray(dir)), rendererOptions.renderer);
}).catch({ isXvfbError: true }, throwFormErrorText(errors.missingXvfb)).catch({ isVerificationError: true }, throwFormErrorText(errors.missingDependency));
}
}], rendererOptions);
return tasks.run();
}
var maybeVerify = function maybeVerify(installedVersion) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
return info.getVerifiedVersion().then(function (verifiedVersion) {
debug('has verified version', verifiedVersion);
// verify if packageVersion and verifiedVersion are different
var shouldVerify = options.force || differentFrom(installedVersion, verifiedVersion);
debug('run verification check?', shouldVerify);
if (shouldVerify) {
return testBinary(installedVersion).then(function () {
if (options.welcomeMessage) {
logger.log();
logger.warn('Opening Cypress...');
}
});
}
});
};
var start = function start() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
debug('verifying Cypress app');
var packageVersion = util.pkgVersion();
_.defaults(options, {
force: false,
welcomeMessage: true
});
return info.getInstalledVersion().then(function (installedVersion) {
debug('installed version is', installedVersion, 'comparing to', packageVersion);
// figure out where this executable is supposed to be at
var executable = info.getPathToExecutable();
return checkIfNotInstalledOrMissingExecutable(installedVersion, executable).return(installedVersion);
}).then(function (installedVersion) {
if (installedVersion !== packageVersion) {
// warn if we installed with CYPRESS_BINARY_VERSION or changed version
// in the package.json
var msg = stripIndent(_templateObject3, chalk.cyan(installedVersion), chalk.cyan(packageVersion));
logger.warn(msg);
logger.log();
}
return maybeVerify(installedVersion, options);
}).catch(function (err) {
if (err.known) {
throw err;
}
return throwFormErrorText(errors.unexpected)(err.stack);
});
};
module.exports = {
start: start,
maybeVerify: maybeVerify
};