init
This commit is contained in:
96
node_modules/cypress/lib/exec/info.js
generated
vendored
Normal file
96
node_modules/cypress/lib/exec/info.js
generated
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
"use strict";
|
||||
|
||||
/* eslint-disable no-console */
|
||||
const spawn = require('./spawn');
|
||||
|
||||
const util = require('../util');
|
||||
|
||||
const state = require('../tasks/state');
|
||||
|
||||
const os = require('os');
|
||||
|
||||
const chalk = require('chalk');
|
||||
|
||||
const prettyBytes = require('pretty-bytes');
|
||||
|
||||
const _ = require('lodash');
|
||||
|
||||
const R = require('ramda'); // color for numbers and show values
|
||||
|
||||
|
||||
const g = chalk.green; // color for paths
|
||||
|
||||
const p = chalk.cyan; // urls
|
||||
|
||||
const link = chalk.blue.underline; // to be exported
|
||||
|
||||
const methods = {};
|
||||
|
||||
methods.findProxyEnvironmentVariables = () => {
|
||||
return _.pick(process.env, ['HTTP_PROXY', 'HTTPS_PROXY', 'NO_PROXY']);
|
||||
};
|
||||
|
||||
const maskSensitiveVariables = R.evolve({
|
||||
CYPRESS_RECORD_KEY: R.always('<redacted>')
|
||||
});
|
||||
|
||||
methods.findCypressEnvironmentVariables = () => {
|
||||
const isCyVariable = (val, key) => key.startsWith('CYPRESS_');
|
||||
|
||||
return R.pickBy(isCyVariable)(process.env);
|
||||
};
|
||||
|
||||
const formatCypressVariables = () => {
|
||||
const vars = methods.findCypressEnvironmentVariables();
|
||||
return maskSensitiveVariables(vars);
|
||||
};
|
||||
|
||||
methods.start = (options = {}) => {
|
||||
const args = ['--mode=info'];
|
||||
return spawn.start(args, {
|
||||
dev: options.dev
|
||||
}).then(() => {
|
||||
console.log();
|
||||
const proxyVars = methods.findProxyEnvironmentVariables();
|
||||
|
||||
if (_.isEmpty(proxyVars)) {
|
||||
console.log('Proxy Settings: none detected');
|
||||
} else {
|
||||
console.log('Proxy Settings:');
|
||||
|
||||
_.forEach(proxyVars, (value, key) => {
|
||||
console.log('%s: %s', key, g(value));
|
||||
});
|
||||
|
||||
console.log();
|
||||
console.log('Learn More: %s', link('https://on.cypress.io/proxy-configuration'));
|
||||
console.log();
|
||||
}
|
||||
}).then(() => {
|
||||
const cyVars = formatCypressVariables();
|
||||
|
||||
if (_.isEmpty(cyVars)) {
|
||||
console.log('Environment Variables: none detected');
|
||||
} else {
|
||||
console.log('Environment Variables:');
|
||||
|
||||
_.forEach(cyVars, (value, key) => {
|
||||
console.log('%s: %s', key, g(value));
|
||||
});
|
||||
}
|
||||
}).then(() => {
|
||||
console.log();
|
||||
console.log('Application Data:', p(util.getApplicationDataFolder()));
|
||||
console.log('Browser Profiles:', p(util.getApplicationDataFolder('browsers')));
|
||||
console.log('Binary Caches: %s', p(state.getCacheDir()));
|
||||
}).then(() => {
|
||||
console.log();
|
||||
return util.getOsVersionAsync().then(osVersion => {
|
||||
console.log('Cypress Version: %s', g(util.pkgVersion()));
|
||||
console.log('System Platform: %s (%s)', g(os.platform()), g(osVersion));
|
||||
console.log('System Memory: %s free %s', g(prettyBytes(os.totalmem())), g(prettyBytes(os.freemem())));
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = methods;
|
66
node_modules/cypress/lib/exec/open.js
generated
vendored
Normal file
66
node_modules/cypress/lib/exec/open.js
generated
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
"use strict";
|
||||
|
||||
const debug = require('debug')('cypress:cli');
|
||||
|
||||
const util = require('../util');
|
||||
|
||||
const spawn = require('./spawn');
|
||||
|
||||
const verify = require('../tasks/verify');
|
||||
|
||||
const {
|
||||
processTestingType
|
||||
} = require('./shared');
|
||||
|
||||
module.exports = {
|
||||
start(options = {}) {
|
||||
if (!util.isInstalledGlobally() && !options.global && !options.project) {
|
||||
options.project = process.cwd();
|
||||
}
|
||||
|
||||
const args = [];
|
||||
|
||||
if (options.config) {
|
||||
args.push('--config', options.config);
|
||||
}
|
||||
|
||||
if (options.configFile !== undefined) {
|
||||
args.push('--config-file', options.configFile);
|
||||
}
|
||||
|
||||
if (options.browser) {
|
||||
args.push('--browser', options.browser);
|
||||
}
|
||||
|
||||
if (options.env) {
|
||||
args.push('--env', options.env);
|
||||
}
|
||||
|
||||
if (options.port) {
|
||||
args.push('--port', options.port);
|
||||
}
|
||||
|
||||
if (options.project) {
|
||||
args.push('--project', options.project);
|
||||
}
|
||||
|
||||
args.push(...processTestingType(options.testingType));
|
||||
debug('opening from options %j', options);
|
||||
debug('command line arguments %j', args);
|
||||
|
||||
function open() {
|
||||
return spawn.start(args, {
|
||||
dev: options.dev,
|
||||
detached: Boolean(options.detached),
|
||||
stdio: 'inherit'
|
||||
});
|
||||
}
|
||||
|
||||
if (options.dev) {
|
||||
return open();
|
||||
}
|
||||
|
||||
return verify.start().then(open);
|
||||
}
|
||||
|
||||
};
|
200
node_modules/cypress/lib/exec/run.js
generated
vendored
Normal file
200
node_modules/cypress/lib/exec/run.js
generated
vendored
Normal file
@@ -0,0 +1,200 @@
|
||||
"use strict";
|
||||
|
||||
const _ = require('lodash');
|
||||
|
||||
const debug = require('debug')('cypress:cli:run');
|
||||
|
||||
const util = require('../util');
|
||||
|
||||
const spawn = require('./spawn');
|
||||
|
||||
const verify = require('../tasks/verify');
|
||||
|
||||
const {
|
||||
exitWithError,
|
||||
errors
|
||||
} = require('../errors');
|
||||
|
||||
const {
|
||||
processTestingType,
|
||||
throwInvalidOptionError
|
||||
} = require('./shared');
|
||||
/**
|
||||
* Typically a user passes a string path to the project.
|
||||
* But "cypress open" allows using `false` to open in global mode,
|
||||
* and the user can accidentally execute `cypress run --project false`
|
||||
* which should be invalid.
|
||||
*/
|
||||
|
||||
|
||||
const isValidProject = v => {
|
||||
if (typeof v === 'boolean') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (v === '' || v === 'false' || v === 'true') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
/**
|
||||
* Maps options collected by the CLI
|
||||
* and forms list of CLI arguments to the server.
|
||||
*
|
||||
* Note: there is lightweight validation, with errors
|
||||
* thrown synchronously.
|
||||
*
|
||||
* @returns {string[]} list of CLI arguments
|
||||
*/
|
||||
|
||||
|
||||
const processRunOptions = (options = {}) => {
|
||||
debug('processing run options %o', options);
|
||||
|
||||
if (!isValidProject(options.project)) {
|
||||
debug('invalid project option %o', {
|
||||
project: options.project
|
||||
});
|
||||
return throwInvalidOptionError(errors.invalidRunProjectPath);
|
||||
}
|
||||
|
||||
const args = ['--run-project', options.project];
|
||||
|
||||
if (options.browser) {
|
||||
args.push('--browser', options.browser);
|
||||
}
|
||||
|
||||
if (options.ciBuildId) {
|
||||
args.push('--ci-build-id', options.ciBuildId);
|
||||
}
|
||||
|
||||
if (options.config) {
|
||||
args.push('--config', options.config);
|
||||
}
|
||||
|
||||
if (options.configFile !== undefined) {
|
||||
args.push('--config-file', options.configFile);
|
||||
}
|
||||
|
||||
if (options.env) {
|
||||
args.push('--env', options.env);
|
||||
}
|
||||
|
||||
if (options.exit === false) {
|
||||
args.push('--no-exit');
|
||||
}
|
||||
|
||||
if (options.group) {
|
||||
args.push('--group', options.group);
|
||||
}
|
||||
|
||||
if (options.headed) {
|
||||
args.push('--headed', options.headed);
|
||||
}
|
||||
|
||||
if (options.headless) {
|
||||
if (options.headed) {
|
||||
return throwInvalidOptionError(errors.incompatibleHeadlessFlags);
|
||||
}
|
||||
|
||||
args.push('--headed', !options.headless);
|
||||
} // if key is set use that - else attempt to find it by environment variable
|
||||
|
||||
|
||||
if (options.key == null) {
|
||||
debug('--key is not set, looking up environment variable CYPRESS_RECORD_KEY');
|
||||
options.key = util.getEnv('CYPRESS_RECORD_KEY');
|
||||
} // if we have a key assume we're in record mode
|
||||
|
||||
|
||||
if (options.key) {
|
||||
args.push('--key', options.key);
|
||||
}
|
||||
|
||||
if (options.outputPath) {
|
||||
args.push('--output-path', options.outputPath);
|
||||
}
|
||||
|
||||
if (options.parallel) {
|
||||
args.push('--parallel');
|
||||
}
|
||||
|
||||
if (options.port) {
|
||||
args.push('--port', options.port);
|
||||
}
|
||||
|
||||
if (options.quiet) {
|
||||
args.push('--quiet');
|
||||
} // if record is defined and we're not
|
||||
// already in ci mode, then send it up
|
||||
|
||||
|
||||
if (options.record != null) {
|
||||
args.push('--record', options.record);
|
||||
} // if we have a specific reporter push that into the args
|
||||
|
||||
|
||||
if (options.reporter) {
|
||||
args.push('--reporter', options.reporter);
|
||||
} // if we have a specific reporter push that into the args
|
||||
|
||||
|
||||
if (options.reporterOptions) {
|
||||
args.push('--reporter-options', options.reporterOptions);
|
||||
} // if we have specific spec(s) push that into the args
|
||||
|
||||
|
||||
if (options.spec) {
|
||||
args.push('--spec', options.spec);
|
||||
}
|
||||
|
||||
if (options.tag) {
|
||||
args.push('--tag', options.tag);
|
||||
}
|
||||
|
||||
args.push(...processTestingType(options.testingType));
|
||||
return args;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
processRunOptions,
|
||||
isValidProject,
|
||||
|
||||
// resolves with the number of failed tests
|
||||
start(options = {}) {
|
||||
_.defaults(options, {
|
||||
key: null,
|
||||
spec: null,
|
||||
reporter: null,
|
||||
reporterOptions: null,
|
||||
project: process.cwd()
|
||||
});
|
||||
|
||||
function run() {
|
||||
let args;
|
||||
|
||||
try {
|
||||
args = processRunOptions(options);
|
||||
} catch (err) {
|
||||
if (err.details) {
|
||||
return exitWithError(err.details)();
|
||||
}
|
||||
|
||||
throw err;
|
||||
}
|
||||
|
||||
debug('run to spawn.start args %j', args);
|
||||
return spawn.start(args, {
|
||||
dev: options.dev
|
||||
});
|
||||
}
|
||||
|
||||
if (options.dev) {
|
||||
return run();
|
||||
}
|
||||
|
||||
return verify.start().then(run);
|
||||
}
|
||||
|
||||
};
|
50
node_modules/cypress/lib/exec/shared.js
generated
vendored
Normal file
50
node_modules/cypress/lib/exec/shared.js
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
"use strict";
|
||||
|
||||
const {
|
||||
errors
|
||||
} = require('../errors');
|
||||
/**
|
||||
* Throws an error with "details" property from
|
||||
* "errors" object.
|
||||
* @param {Object} details - Error details
|
||||
*/
|
||||
|
||||
|
||||
const throwInvalidOptionError = details => {
|
||||
if (!details) {
|
||||
details = errors.unknownError;
|
||||
} // throw this error synchronously, it will be caught later on and
|
||||
// the details will be propagated to the promise chain
|
||||
|
||||
|
||||
const err = new Error();
|
||||
err.details = details;
|
||||
throw err;
|
||||
};
|
||||
/**
|
||||
* Selects exec args based on the configured `testingType`
|
||||
* @param {string} testingType The type of tests being executed
|
||||
* @returns {string[]} The array of new exec arguments
|
||||
*/
|
||||
|
||||
|
||||
const processTestingType = testingType => {
|
||||
if (testingType) {
|
||||
if (testingType === 'e2e') {
|
||||
return ['--testing-type', 'e2e'];
|
||||
}
|
||||
|
||||
if (testingType === 'component') {
|
||||
return ['--testing-type', 'component'];
|
||||
}
|
||||
|
||||
return throwInvalidOptionError(errors.invalidTestingType);
|
||||
}
|
||||
|
||||
return [];
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
throwInvalidOptionError,
|
||||
processTestingType
|
||||
};
|
299
node_modules/cypress/lib/exec/spawn.js
generated
vendored
Normal file
299
node_modules/cypress/lib/exec/spawn.js
generated
vendored
Normal file
@@ -0,0 +1,299 @@
|
||||
"use strict";
|
||||
|
||||
const _ = require('lodash');
|
||||
|
||||
const os = require('os');
|
||||
|
||||
const cp = require('child_process');
|
||||
|
||||
const path = require('path');
|
||||
|
||||
const Promise = require('bluebird');
|
||||
|
||||
const debug = require('debug')('cypress:cli');
|
||||
|
||||
const debugElectron = require('debug')('cypress:electron');
|
||||
|
||||
const util = require('../util');
|
||||
|
||||
const state = require('../tasks/state');
|
||||
|
||||
const xvfb = require('./xvfb');
|
||||
|
||||
const verify = require('../tasks/verify');
|
||||
|
||||
const errors = require('../errors');
|
||||
|
||||
const isXlibOrLibudevRe = /^(?:Xlib|libudev)/;
|
||||
const isHighSierraWarningRe = /\*\*\* WARNING/;
|
||||
const isRenderWorkerRe = /\.RenderWorker-/;
|
||||
const GARBAGE_WARNINGS = [isXlibOrLibudevRe, isHighSierraWarningRe, isRenderWorkerRe];
|
||||
|
||||
const isGarbageLineWarning = str => {
|
||||
return _.some(GARBAGE_WARNINGS, re => {
|
||||
return re.test(str);
|
||||
});
|
||||
};
|
||||
|
||||
function isPlatform(platform) {
|
||||
return os.platform() === platform;
|
||||
}
|
||||
|
||||
function needsStderrPiped(needsXvfb) {
|
||||
return _.some([isPlatform('darwin'), needsXvfb && isPlatform('linux'), util.isPossibleLinuxWithIncorrectDisplay()]);
|
||||
}
|
||||
|
||||
function needsEverythingPipedDirectly() {
|
||||
return isPlatform('win32');
|
||||
}
|
||||
|
||||
function getStdio(needsXvfb) {
|
||||
if (needsEverythingPipedDirectly()) {
|
||||
return 'pipe';
|
||||
} // https://github.com/cypress-io/cypress/issues/921
|
||||
// https://github.com/cypress-io/cypress/issues/1143
|
||||
// https://github.com/cypress-io/cypress/issues/1745
|
||||
|
||||
|
||||
if (needsStderrPiped(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 = {
|
||||
isGarbageLineWarning,
|
||||
|
||||
start(args, options = {}) {
|
||||
const needsXvfb = xvfb.isNeeded();
|
||||
let executable = state.getPathToExecutable(state.getBinaryDir());
|
||||
|
||||
if (util.getEnv('CYPRESS_RUN_BINARY')) {
|
||||
executable = path.resolve(util.getEnv('CYPRESS_RUN_BINARY'));
|
||||
}
|
||||
|
||||
debug('needs to start own Xvfb?', needsXvfb); // Always push cwd into the args
|
||||
// which additionally acts as a signal to the
|
||||
// binary that it was invoked through the NPM module
|
||||
|
||||
args = args || [];
|
||||
|
||||
if (typeof args === 'string') {
|
||||
args = [args];
|
||||
}
|
||||
|
||||
args = [...args, '--cwd', process.cwd()];
|
||||
|
||||
_.defaults(options, {
|
||||
dev: false,
|
||||
env: process.env,
|
||||
detached: false,
|
||||
stdio: getStdio(needsXvfb)
|
||||
});
|
||||
|
||||
const spawn = (overrides = {}) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
_.defaults(overrides, {
|
||||
onStderrData: false,
|
||||
electronLogging: false
|
||||
});
|
||||
|
||||
const {
|
||||
onStderrData,
|
||||
electronLogging
|
||||
} = overrides;
|
||||
const envOverrides = util.getEnvOverrides(options);
|
||||
const electronArgs = [];
|
||||
const node11WindowsFix = isPlatform('win32');
|
||||
|
||||
if (options.dev) {
|
||||
// if we're in dev then reset
|
||||
// the launch cmd to be 'npm run dev'
|
||||
executable = 'node';
|
||||
electronArgs.unshift(path.resolve(__dirname, '..', '..', '..', 'scripts', 'start.js'));
|
||||
debug('in dev mode the args became %o', args);
|
||||
}
|
||||
|
||||
if (!options.dev && verify.needsSandbox()) {
|
||||
electronArgs.push('--no-sandbox');
|
||||
} // strip dev out of child process options
|
||||
|
||||
|
||||
let stdioOptions = _.pick(options, 'env', 'detached', 'stdio'); // figure out if we're going to be force enabling or disabling colors.
|
||||
// also figure out whether we should force stdout and stderr into thinking
|
||||
// it is a tty as opposed to a pipe.
|
||||
|
||||
|
||||
stdioOptions.env = _.extend({}, stdioOptions.env, envOverrides);
|
||||
|
||||
if (node11WindowsFix) {
|
||||
stdioOptions = _.extend({}, stdioOptions, {
|
||||
windowsHide: false
|
||||
});
|
||||
}
|
||||
|
||||
if (electronLogging) {
|
||||
stdioOptions.env.ELECTRON_ENABLE_LOGGING = true;
|
||||
}
|
||||
|
||||
if (util.isPossibleLinuxWithIncorrectDisplay()) {
|
||||
// make sure we use the latest DISPLAY variable if any
|
||||
debug('passing DISPLAY', process.env.DISPLAY);
|
||||
stdioOptions.env.DISPLAY = process.env.DISPLAY;
|
||||
}
|
||||
|
||||
if (stdioOptions.env.ELECTRON_RUN_AS_NODE) {
|
||||
// Since we are running electron as node, we need to add an entry point file.
|
||||
const serverEntryPoint = path.join(state.getBinaryPkgPath(path.dirname(executable)), '..', 'index.js');
|
||||
args = [serverEntryPoint, ...args];
|
||||
} else {
|
||||
// Start arguments with "--" so Electron knows these are OUR
|
||||
// arguments and does not try to sanitize them. Otherwise on Windows
|
||||
// an url in one of the arguments crashes it :(
|
||||
// https://github.com/cypress-io/cypress/issues/5466
|
||||
args = [...electronArgs, '--', ...args];
|
||||
}
|
||||
|
||||
debug('spawning Cypress with executable: %s', executable);
|
||||
debug('spawn args %o %o', args, _.omit(stdioOptions, 'env'));
|
||||
const child = cp.spawn(executable, args, stdioOptions);
|
||||
|
||||
function resolveOn(event) {
|
||||
return function (code, signal) {
|
||||
debug('child event fired %o', {
|
||||
event,
|
||||
code,
|
||||
signal
|
||||
});
|
||||
|
||||
if (code === null) {
|
||||
const errorObject = errors.errors.childProcessKilled(event, signal);
|
||||
return errors.getError(errorObject).then(reject);
|
||||
}
|
||||
|
||||
resolve(code);
|
||||
};
|
||||
}
|
||||
|
||||
child.on('close', resolveOn('close'));
|
||||
child.on('exit', resolveOn('exit'));
|
||||
child.on('error', reject); // if stdio options is set to 'pipe', then
|
||||
// we should set up pipes:
|
||||
// process STDIN (read stream) => child STDIN (writeable)
|
||||
// child STDOUT => process STDOUT
|
||||
// child STDERR => process STDERR with additional filtering
|
||||
|
||||
if (child.stdin) {
|
||||
debug('piping process STDIN into child STDIN');
|
||||
process.stdin.pipe(child.stdin);
|
||||
}
|
||||
|
||||
if (child.stdout) {
|
||||
debug('piping child STDOUT to process STDOUT');
|
||||
child.stdout.pipe(process.stdout);
|
||||
} // if this is defined then we are manually piping for linux
|
||||
// to filter out the garbage
|
||||
|
||||
|
||||
if (child.stderr) {
|
||||
debug('piping child STDERR to process STDERR');
|
||||
child.stderr.on('data', data => {
|
||||
const str = data.toString(); // bail if this is warning line garbage
|
||||
|
||||
if (isGarbageLineWarning(str)) {
|
||||
return;
|
||||
} // if we have a callback and this explictly returns
|
||||
// false then bail
|
||||
|
||||
|
||||
if (onStderrData && onStderrData(str) === false) {
|
||||
return;
|
||||
} // else pass it along!
|
||||
|
||||
|
||||
process.stderr.write(data);
|
||||
});
|
||||
} // https://github.com/cypress-io/cypress/issues/1841
|
||||
// https://github.com/cypress-io/cypress/issues/5241
|
||||
// In some versions of node, it will throw on windows
|
||||
// when you close the parent process after piping
|
||||
// into the child process. unpiping does not seem
|
||||
// to have any effect. so we're just catching the
|
||||
// error here and not doing anything.
|
||||
|
||||
|
||||
process.stdin.on('error', err => {
|
||||
if (['EPIPE', 'ENOTCONN'].includes(err.code)) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw err;
|
||||
});
|
||||
|
||||
if (stdioOptions.detached) {
|
||||
child.unref();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const spawnInXvfb = () => {
|
||||
return xvfb.start().then(userFriendlySpawn).finally(xvfb.stop);
|
||||
};
|
||||
|
||||
const userFriendlySpawn = linuxWithDisplayEnv => {
|
||||
debug('spawning, should retry on display problem?', Boolean(linuxWithDisplayEnv));
|
||||
let brokenGtkDisplay;
|
||||
const overrides = {};
|
||||
|
||||
if (linuxWithDisplayEnv) {
|
||||
_.extend(overrides, {
|
||||
electronLogging: true,
|
||||
|
||||
onStderrData(str) {
|
||||
// if we receive a broken pipe anywhere
|
||||
// then we know that's why cypress exited early
|
||||
if (util.isBrokenGtkDisplay(str)) {
|
||||
brokenGtkDisplay = true;
|
||||
} // we should attempt to always slurp up
|
||||
// the stderr logs unless we've explicitly
|
||||
// enabled the electron debug logging
|
||||
|
||||
|
||||
if (!debugElectron.enabled) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
return spawn(overrides).then(code => {
|
||||
if (code !== 0 && brokenGtkDisplay) {
|
||||
util.logBrokenGtkDisplayWarning();
|
||||
return spawnInXvfb();
|
||||
}
|
||||
|
||||
return code;
|
||||
}) // we can format and handle an error message from the code above
|
||||
// prevent wrapping error again by using "known: undefined" filter
|
||||
.catch({
|
||||
known: undefined
|
||||
}, errors.throwFormErrorText(errors.errors.unexpected));
|
||||
};
|
||||
|
||||
if (needsXvfb) {
|
||||
return spawnInXvfb();
|
||||
} // if we are on linux and there's already a DISPLAY
|
||||
// set, then we may need to rerun cypress after
|
||||
// spawning our own Xvfb server
|
||||
|
||||
|
||||
const linuxWithDisplayEnv = util.isPossibleLinuxWithIncorrectDisplay();
|
||||
return userFriendlySpawn(linuxWithDisplayEnv);
|
||||
}
|
||||
|
||||
};
|
59
node_modules/cypress/lib/exec/versions.js
generated
vendored
Normal file
59
node_modules/cypress/lib/exec/versions.js
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
"use strict";
|
||||
|
||||
const Promise = require('bluebird');
|
||||
|
||||
const debug = require('debug')('cypress:cli');
|
||||
|
||||
const path = require('path');
|
||||
|
||||
const util = require('../util');
|
||||
|
||||
const state = require('../tasks/state');
|
||||
|
||||
const {
|
||||
throwFormErrorText,
|
||||
errors
|
||||
} = require('../errors');
|
||||
|
||||
const getVersions = () => {
|
||||
return Promise.try(() => {
|
||||
if (util.getEnv('CYPRESS_RUN_BINARY')) {
|
||||
let envBinaryPath = path.resolve(util.getEnv('CYPRESS_RUN_BINARY'));
|
||||
return state.parseRealPlatformBinaryFolderAsync(envBinaryPath).then(envBinaryDir => {
|
||||
if (!envBinaryDir) {
|
||||
return throwFormErrorText(errors.CYPRESS_RUN_BINARY.notValid(envBinaryPath))();
|
||||
}
|
||||
|
||||
debug('CYPRESS_RUN_BINARY has binaryDir:', envBinaryDir);
|
||||
return envBinaryDir;
|
||||
}).catch({
|
||||
code: 'ENOENT'
|
||||
}, err => {
|
||||
return throwFormErrorText(errors.CYPRESS_RUN_BINARY.notValid(envBinaryPath))(err.message);
|
||||
});
|
||||
}
|
||||
|
||||
return state.getBinaryDir();
|
||||
}).then(state.getBinaryPkgAsync).then(pkg => {
|
||||
const versions = {
|
||||
binary: state.getBinaryPkgVersion(pkg),
|
||||
electronVersion: state.getBinaryElectronVersion(pkg),
|
||||
electronNodeVersion: state.getBinaryElectronNodeVersion(pkg)
|
||||
};
|
||||
debug('binary versions %o', versions);
|
||||
return versions;
|
||||
}).then(binaryVersions => {
|
||||
const versions = {
|
||||
package: util.pkgVersion(),
|
||||
binary: binaryVersions.binary || 'not installed',
|
||||
electronVersion: binaryVersions.electronVersion || 'not found',
|
||||
electronNodeVersion: binaryVersions.electronNodeVersion || 'not found'
|
||||
};
|
||||
debug('combined versions %o', versions);
|
||||
return versions;
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
getVersions
|
||||
};
|
106
node_modules/cypress/lib/exec/xvfb.js
generated
vendored
Normal file
106
node_modules/cypress/lib/exec/xvfb.js
generated
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
"use strict";
|
||||
|
||||
const os = require('os');
|
||||
|
||||
const Promise = require('bluebird');
|
||||
|
||||
const Xvfb = require('@cypress/xvfb');
|
||||
|
||||
const {
|
||||
stripIndent
|
||||
} = require('common-tags');
|
||||
|
||||
const Debug = require('debug');
|
||||
|
||||
const {
|
||||
throwFormErrorText,
|
||||
errors
|
||||
} = require('../errors');
|
||||
|
||||
const util = require('../util');
|
||||
|
||||
const debug = Debug('cypress:cli');
|
||||
const debugXvfb = Debug('cypress:xvfb');
|
||||
debug.Debug = debugXvfb.Debug = Debug;
|
||||
const xvfbOptions = {
|
||||
timeout: 30000,
|
||||
// milliseconds
|
||||
// need to explicitly define screen otherwise electron will crash
|
||||
// https://github.com/cypress-io/cypress/issues/6184
|
||||
xvfb_args: ['-screen', '0', '1280x1024x24'],
|
||||
|
||||
onStderrData(data) {
|
||||
if (debugXvfb.enabled) {
|
||||
debugXvfb(data.toString());
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
const xvfb = Promise.promisifyAll(new Xvfb(xvfbOptions));
|
||||
module.exports = {
|
||||
_debugXvfb: debugXvfb,
|
||||
// expose for testing
|
||||
_xvfb: xvfb,
|
||||
// expose for testing
|
||||
_xvfbOptions: xvfbOptions,
|
||||
|
||||
// expose for testing
|
||||
start() {
|
||||
debug('Starting Xvfb');
|
||||
return xvfb.startAsync().return(null).catch({
|
||||
nonZeroExitCode: true
|
||||
}, throwFormErrorText(errors.nonZeroExitCodeXvfb)).catch(err => {
|
||||
if (err.known) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
return throwFormErrorText(errors.missingXvfb)(err);
|
||||
});
|
||||
},
|
||||
|
||||
stop() {
|
||||
debug('Stopping Xvfb');
|
||||
return xvfb.stopAsync().return(null).catch(() => {// noop
|
||||
});
|
||||
},
|
||||
|
||||
isNeeded() {
|
||||
if (process.env.ELECTRON_RUN_AS_NODE) {
|
||||
debug('Environment variable ELECTRON_RUN_AS_NODE detected, xvfb is not needed');
|
||||
return false; // xvfb required for electron processes only.
|
||||
}
|
||||
|
||||
if (os.platform() !== 'linux') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (process.env.DISPLAY) {
|
||||
const issueUrl = util.getGitHubIssueUrl(4034);
|
||||
const message = stripIndent`
|
||||
DISPLAY environment variable is set to ${process.env.DISPLAY} on Linux
|
||||
Assuming this DISPLAY points at working X11 server,
|
||||
Cypress will not spawn own Xvfb
|
||||
|
||||
NOTE: if the X11 server is NOT working, Cypress will exit without explanation,
|
||||
see ${issueUrl}
|
||||
Solution: Unset the DISPLAY variable and try again:
|
||||
DISPLAY= npx cypress run ...
|
||||
`;
|
||||
debug(message);
|
||||
return false;
|
||||
}
|
||||
|
||||
debug('undefined DISPLAY environment variable');
|
||||
debug('Cypress will spawn its own Xvfb');
|
||||
return true;
|
||||
},
|
||||
|
||||
// async method, resolved with Boolean
|
||||
verify() {
|
||||
return xvfb.startAsync().return(true).catch(err => {
|
||||
debug('Could not verify xvfb: %s', err.message);
|
||||
return false;
|
||||
}).finally(xvfb.stopAsync);
|
||||
}
|
||||
|
||||
};
|
Reference in New Issue
Block a user