This commit is contained in:
Lukáš Kaňka
2023-08-15 18:35:50 +02:00
commit ea3e372146
10019 changed files with 2548539 additions and 0 deletions

View File

@ -0,0 +1,58 @@
"use strict";
// Vendored from @cypress/listr-verbose-renderer
const figures = require('figures');
const cliCursor = require('cli-cursor');
const chalk = require('chalk');
const dayjs = require('dayjs');
const formattedLog = (options, output) => {
const timestamp = dayjs().format(options.dateFormat);
// eslint-disable-next-line no-console
console.log(`${chalk.dim(`[${timestamp}]`)} ${output}`);
};
const renderHelper = (task, event, options) => {
const log = formattedLog.bind(undefined, options);
if (event.type === 'STATE') {
const message = task.isPending() ? 'started' : task.state;
log(`${task.title} [${message}]`);
if (task.isSkipped() && task.output) {
log(`${figures.arrowRight} ${task.output}`);
}
} else if (event.type === 'TITLE') {
log(`${task.title} [title changed]`);
}
};
const render = (tasks, options) => {
for (const task of tasks) {
task.subscribe(event => {
if (event.type === 'SUBTASKS') {
render(task.subtasks, options);
return;
}
renderHelper(task, event, options);
}, err => {
// eslint-disable-next-line no-console
console.log(err);
});
}
};
class VerboseRenderer {
constructor(tasks, options) {
this._tasks = tasks;
this._options = Object.assign({
dateFormat: 'HH:mm:ss'
}, options);
}
static get nonTTY() {
return true;
}
render() {
cliCursor.hide();
render(this._tasks, this._options);
}
end() {
cliCursor.show();
}
}
module.exports = VerboseRenderer;

439
CyLukTs/lukan/node_modules/cypress/lib/cli.js generated vendored Normal file
View File

@ -0,0 +1,439 @@
"use strict";
// @ts-check
const _ = require('lodash');
const commander = require('commander');
const {
stripIndent
} = require('common-tags');
const logSymbols = require('log-symbols');
const debug = require('debug')('cypress:cli:cli');
const util = require('./util');
const logger = require('./logger');
const errors = require('./errors');
const cache = require('./tasks/cache');
// patch "commander" method called when a user passed an unknown option
// we want to print help for the current command and exit with an error
function unknownOption(flag, type = 'option') {
if (this._allowUnknownOption) return;
logger.error();
logger.error(` error: unknown ${type}:`, flag);
logger.error();
this.outputHelp();
util.exit(1);
}
commander.Command.prototype.unknownOption = unknownOption;
const coerceFalse = arg => {
return arg !== 'false';
};
const coerceAnyStringToInt = arg => {
return typeof arg === 'string' ? parseInt(arg) : arg;
};
const spaceDelimitedArgsMsg = (flag, args) => {
let msg = `
${logSymbols.warning} Warning: It looks like you're passing --${flag} a space-separated list of arguments:
"${args.join(' ')}"
This will work, but it's not recommended.
If you are trying to pass multiple arguments, separate them with commas instead:
cypress run --${flag} arg1,arg2,arg3
`;
if (flag === 'spec') {
msg += `
The most common cause of this warning is using an unescaped glob pattern. If you are
trying to pass a glob pattern, escape it using quotes:
cypress run --spec "**/*.spec.js"
`;
}
logger.log();
logger.warn(stripIndent(msg));
logger.log();
};
const parseVariableOpts = (fnArgs, args) => {
const [opts, unknownArgs] = fnArgs;
if (unknownArgs && unknownArgs.length && (opts.spec || opts.tag)) {
// this will capture space-delimited args after
// flags that could have possible multiple args
// but before the next option
// --spec spec1 spec2 or --tag foo bar
const multiArgFlags = _.compact([opts.spec ? 'spec' : opts.spec, opts.tag ? 'tag' : opts.tag]);
_.forEach(multiArgFlags, flag => {
const argIndex = _.indexOf(args, `--${flag}`) + 2;
const nextOptOffset = _.findIndex(_.slice(args, argIndex), arg => {
return _.startsWith(arg, '--');
});
const endIndex = nextOptOffset !== -1 ? argIndex + nextOptOffset : args.length;
const maybeArgs = _.slice(args, argIndex, endIndex);
const extraArgs = _.intersection(maybeArgs, unknownArgs);
if (extraArgs.length) {
opts[flag] = [opts[flag]].concat(extraArgs);
spaceDelimitedArgsMsg(flag, opts[flag]);
opts[flag] = opts[flag].join(',');
}
});
}
debug('variable-length opts parsed %o', {
args,
opts
});
return util.parseOpts(opts);
};
const descriptions = {
autoCancelAfterFailures: 'overrides the project-level Cloud configuration to set the failed test threshold for auto cancellation or to disable auto cancellation when recording to the Cloud',
browser: 'runs Cypress in the browser with the given name. if a filesystem path is supplied, Cypress will attempt to use the browser at that path.',
cacheClear: 'delete all cached binaries',
cachePrune: 'deletes all cached binaries except for the version currently in use',
cacheList: 'list cached binary versions',
cachePath: 'print the path to the binary cache',
cacheSize: 'Used with the list command to show the sizes of the cached folders',
ciBuildId: 'the unique identifier for a run on your CI provider. typically a "BUILD_ID" env var. this value is automatically detected for most CI providers',
component: 'runs component tests',
config: 'sets configuration values. separate multiple values with a comma. overrides any value in cypress.config.{js,ts,mjs,cjs}.',
configFile: 'path to script file where configuration values are set. defaults to "cypress.config.{js,ts,mjs,cjs}".',
detached: 'runs Cypress application in detached mode',
dev: 'runs cypress in development and bypasses binary check',
e2e: 'runs end to end tests',
env: 'sets environment variables. separate multiple values with a comma. overrides any value in cypress.config.{js,ts,mjs,cjs} or cypress.env.json',
exit: 'keep the browser open after tests finish',
forceInstall: 'force install the Cypress binary',
global: 'force Cypress into global mode as if its globally installed',
group: 'a named group for recorded runs in Cypress Cloud',
headed: 'displays the browser instead of running headlessly',
headless: 'hide the browser instead of running headed (default for cypress run)',
key: 'your secret Record Key. you can omit this if you set a CYPRESS_RECORD_KEY environment variable.',
parallel: 'enables concurrent runs and automatic load balancing of specs across multiple machines or processes',
port: 'runs Cypress on a specific port. overrides any value in cypress.config.{js,ts,mjs,cjs}.',
project: 'path to the project',
quiet: 'run quietly, using only the configured reporter',
record: 'records the run. sends test results, screenshots and videos to Cypress Cloud.',
reporter: 'runs a specific mocha reporter. pass a path to use a custom reporter. defaults to "spec"',
reporterOptions: 'options for the mocha reporter. defaults to "null"',
spec: 'runs specific spec file(s). defaults to "all"',
tag: 'named tag(s) for recorded runs in Cypress Cloud',
version: 'prints Cypress version'
};
const knownCommands = ['cache', 'help', '-h', '--help', 'install', 'open', 'run', 'open-ct', 'run-ct', 'verify', '-v', '--version', 'version', 'info'];
const text = description => {
if (!descriptions[description]) {
throw new Error(`Could not find description for: ${description}`);
}
return descriptions[description];
};
function includesVersion(args) {
return _.includes(args, '--version') || _.includes(args, '-v');
}
function showVersions(opts) {
debug('printing Cypress version');
debug('additional arguments %o', opts);
debug('parsed version arguments %o', opts);
const reportAllVersions = versions => {
logger.always('Cypress package version:', versions.package);
logger.always('Cypress binary version:', versions.binary);
logger.always('Electron version:', versions.electronVersion);
logger.always('Bundled Node version:', versions.electronNodeVersion);
};
const reportComponentVersion = (componentName, versions) => {
const names = {
package: 'package',
binary: 'binary',
electron: 'electronVersion',
node: 'electronNodeVersion'
};
if (!names[componentName]) {
throw new Error(`Unknown component name "${componentName}"`);
}
const name = names[componentName];
if (!versions[name]) {
throw new Error(`Cannot find version for component "${componentName}" under property "${name}"`);
}
const version = versions[name];
logger.always(version);
};
const defaultVersions = {
package: undefined,
binary: undefined,
electronVersion: undefined,
electronNodeVersion: undefined
};
return require('./exec/versions').getVersions().then((versions = defaultVersions) => {
if (opts !== null && opts !== void 0 && opts.component) {
reportComponentVersion(opts.component, versions);
} else {
reportAllVersions(versions);
}
process.exit(0);
}).catch(util.logErrorExit1);
}
const createProgram = () => {
const program = new commander.Command();
// bug in commander not printing name
// in usage help docs
program._name = 'cypress';
program.usage('<command> [options]');
return program;
};
const addCypressRunCommand = program => {
return program.command('run').usage('[options]').description('Runs Cypress tests from the CLI without the GUI').option('--auto-cancel-after-failures <test-failure-count || false>', text('autoCancelAfterFailures')).option('-b, --browser <browser-name-or-path>', text('browser')).option('--ci-build-id <id>', text('ciBuildId')).option('--component', text('component')).option('-c, --config <config>', text('config')).option('-C, --config-file <config-file>', text('configFile')).option('--e2e', text('e2e')).option('-e, --env <env>', text('env')).option('--group <name>', text('group')).option('-k, --key <record-key>', text('key')).option('--headed', text('headed')).option('--headless', text('headless')).option('--no-exit', text('exit')).option('--parallel', text('parallel')).option('-p, --port <port>', text('port')).option('-P, --project <project-path>', text('project')).option('-q, --quiet', text('quiet')).option('--record [bool]', text('record'), coerceFalse).option('-r, --reporter <reporter>', text('reporter')).option('-o, --reporter-options <reporter-options>', text('reporterOptions')).option('-s, --spec <spec>', text('spec')).option('-t, --tag <tag>', text('tag')).option('--dev', text('dev'), coerceFalse);
};
const addCypressOpenCommand = program => {
return program.command('open').usage('[options]').description('Opens Cypress in the interactive GUI.').option('-b, --browser <browser-path>', text('browser')).option('--component', text('component')).option('-c, --config <config>', text('config')).option('-C, --config-file <config-file>', text('configFile')).option('-d, --detached [bool]', text('detached'), coerceFalse).option('--e2e', text('e2e')).option('-e, --env <env>', text('env')).option('--global', text('global')).option('-p, --port <port>', text('port')).option('-P, --project <project-path>', text('project')).option('--dev', text('dev'), coerceFalse);
};
const maybeAddInspectFlags = program => {
if (process.argv.includes('--dev')) {
return program.option('--inspect', 'Node option').option('--inspect-brk', 'Node option');
}
return program;
};
/**
* Casts known command line options for "cypress run" to their intended type.
* For example if the user passes "--port 5005" the ".port" property should be
* a number 5005 and not a string "5005".
*
* Returns a clone of the original object.
*/
const castCypressOptions = opts => {
// only properties that have type "string | false" in our TS definition
// require special handling, because CLI parsing takes care of purely
// boolean arguments
const castOpts = {
...opts
};
if (_.has(opts, 'port')) {
castOpts.port = coerceAnyStringToInt(opts.port);
}
return castOpts;
};
module.exports = {
/**
* Parses `cypress run` command line option array into an object
* with options that you can feed into a `cypress.run()` module API call.
* @example
* const options = parseRunCommand(['cypress', 'run', '--browser', 'chrome'])
* // options is {browser: 'chrome'}
*/
parseRunCommand(args) {
return new Promise((resolve, reject) => {
if (!Array.isArray(args)) {
return reject(new Error('Expected array of arguments'));
}
// make a copy of the input arguments array
// and add placeholders where "node ..." would usually be
// also remove "cypress" keyword at the start if present
const cliArgs = args[0] === 'cypress' ? [...args.slice(1)] : [...args];
cliArgs.unshift(null, null);
debug('creating program parser');
const program = createProgram();
maybeAddInspectFlags(addCypressRunCommand(program)).action((...fnArgs) => {
debug('parsed Cypress run %o', fnArgs);
const options = parseVariableOpts(fnArgs, cliArgs);
debug('parsed options %o', options);
const casted = castCypressOptions(options);
debug('casted options %o', casted);
resolve(casted);
});
debug('parsing args: %o', cliArgs);
program.parse(cliArgs);
});
},
/**
* Parses `cypress open` command line option array into an object
* with options that you can feed into cy.openModeSystemTest test calls
* @example
* const options = parseOpenCommand(['cypress', 'open', '--browser', 'chrome'])
* // options is {browser: 'chrome'}
*/
parseOpenCommand(args) {
return new Promise((resolve, reject) => {
if (!Array.isArray(args)) {
return reject(new Error('Expected array of arguments'));
}
// make a copy of the input arguments array
// and add placeholders where "node ..." would usually be
// also remove "cypress" keyword at the start if present
const cliArgs = args[0] === 'cypress' ? [...args.slice(1)] : [...args];
cliArgs.unshift(null, null);
debug('creating program parser');
const program = createProgram();
maybeAddInspectFlags(addCypressOpenCommand(program)).action((...fnArgs) => {
debug('parsed Cypress open %o', fnArgs);
const options = parseVariableOpts(fnArgs, cliArgs);
debug('parsed options %o', options);
const casted = castCypressOptions(options);
debug('casted options %o', casted);
resolve(casted);
});
debug('parsing args: %o', cliArgs);
program.parse(cliArgs);
});
},
/**
* Parses the command line and kicks off Cypress process.
*/
init(args) {
if (!args) {
args = process.argv;
}
const {
CYPRESS_INTERNAL_ENV,
CYPRESS_DOWNLOAD_USE_CA
} = process.env;
if (process.env.CYPRESS_DOWNLOAD_USE_CA) {
let msg = `
${logSymbols.warning} Warning: It looks like you're setting CYPRESS_DOWNLOAD_USE_CA=${CYPRESS_DOWNLOAD_USE_CA}
The environment variable "CYPRESS_DOWNLOAD_USE_CA" is no longer required to be set.
You can safely unset this environment variable.
`;
logger.log();
logger.warn(stripIndent(msg));
logger.log();
}
if (!util.isValidCypressInternalEnvValue(CYPRESS_INTERNAL_ENV)) {
debug('invalid CYPRESS_INTERNAL_ENV value', CYPRESS_INTERNAL_ENV);
return errors.exitWithError(errors.errors.invalidCypressEnv)(`CYPRESS_INTERNAL_ENV=${CYPRESS_INTERNAL_ENV}`);
}
if (util.isNonProductionCypressInternalEnvValue(CYPRESS_INTERNAL_ENV)) {
debug('non-production CYPRESS_INTERNAL_ENV value', CYPRESS_INTERNAL_ENV);
let msg = `
${logSymbols.warning} Warning: It looks like you're passing CYPRESS_INTERNAL_ENV=${CYPRESS_INTERNAL_ENV}
The environment variable "CYPRESS_INTERNAL_ENV" is reserved and should only be used internally.
Unset the "CYPRESS_INTERNAL_ENV" environment variable and run Cypress again.
`;
logger.log();
logger.warn(stripIndent(msg));
logger.log();
}
const program = createProgram();
program.command('help').description('Shows CLI help and exits').action(() => {
program.help();
});
const handleVersion = cmd => {
return cmd.option('--component <package|binary|electron|node>', 'component to report version for').action((opts, ...other) => {
showVersions(util.parseOpts(opts));
});
};
handleVersion(program.storeOptionsAsProperties().option('-v, --version', text('version')).command('version').description(text('version')));
maybeAddInspectFlags(addCypressOpenCommand(program)).action(opts => {
debug('opening Cypress');
require('./exec/open').start(util.parseOpts(opts)).then(util.exit).catch(util.logErrorExit1);
});
maybeAddInspectFlags(addCypressRunCommand(program)).action((...fnArgs) => {
debug('running Cypress with args %o', fnArgs);
require('./exec/run').start(parseVariableOpts(fnArgs, args)).then(util.exit).catch(util.logErrorExit1);
});
program.command('open-ct').usage('[options]').description('Opens Cypress component testing interactive mode. Deprecated: use "open --component"').option('-b, --browser <browser-path>', text('browser')).option('-c, --config <config>', text('config')).option('-C, --config-file <config-file>', text('configFile')).option('-d, --detached [bool]', text('detached'), coerceFalse).option('-e, --env <env>', text('env')).option('--global', text('global')).option('-p, --port <port>', text('port')).option('-P, --project <project-path>', text('project')).option('--dev', text('dev'), coerceFalse).action(opts => {
debug('opening Cypress');
const msg = `
${logSymbols.warning} Warning: open-ct is deprecated and will be removed in a future release.
Use \`cypress open --component\` instead.
`;
logger.warn();
logger.warn(stripIndent(msg));
logger.warn();
require('./exec/open').start({
...util.parseOpts(opts),
testingType: 'component'
}).then(util.exit).catch(util.logErrorExit1);
});
program.command('run-ct').usage('[options]').description('Runs all Cypress component testing suites. Deprecated: use "run --component"').option('-b, --browser <browser-name-or-path>', text('browser')).option('--ci-build-id <id>', text('ciBuildId')).option('-c, --config <config>', text('config')).option('-C, --config-file <config-file>', text('configFile')).option('-e, --env <env>', text('env')).option('--group <name>', text('group')).option('-k, --key <record-key>', text('key')).option('--headed', text('headed')).option('--headless', text('headless')).option('--no-exit', text('exit')).option('--parallel', text('parallel')).option('-p, --port <port>', text('port')).option('-P, --project <project-path>', text('project')).option('-q, --quiet', text('quiet')).option('--record [bool]', text('record'), coerceFalse).option('-r, --reporter <reporter>', text('reporter')).option('-o, --reporter-options <reporter-options>', text('reporterOptions')).option('-s, --spec <spec>', text('spec')).option('-t, --tag <tag>', text('tag')).option('--dev', text('dev'), coerceFalse).action(opts => {
debug('running Cypress run-ct');
const msg = `
${logSymbols.warning} Warning: run-ct is deprecated and will be removed in a future release.
Use \`cypress run --component\` instead.
`;
logger.warn();
logger.warn(stripIndent(msg));
logger.warn();
require('./exec/run').start({
...util.parseOpts(opts),
testingType: 'component'
}).then(util.exit).catch(util.logErrorExit1);
});
program.command('install').usage('[options]').description('Installs the Cypress executable matching this package\'s version').option('-f, --force', text('forceInstall')).action(opts => {
require('./tasks/install').start(util.parseOpts(opts)).catch(util.logErrorExit1);
});
program.command('verify').usage('[options]').description('Verifies that Cypress is installed correctly and executable').option('--dev', text('dev'), coerceFalse).action(opts => {
const defaultOpts = {
force: true,
welcomeMessage: false
};
const parsedOpts = util.parseOpts(opts);
const options = _.extend(parsedOpts, defaultOpts);
require('./tasks/verify').start(options).catch(util.logErrorExit1);
});
program.command('cache').usage('[command]').description('Manages the Cypress binary cache').option('list', text('cacheList')).option('path', text('cachePath')).option('clear', text('cacheClear')).option('prune', text('cachePrune')).option('--size', text('cacheSize')).action(function (opts, args) {
if (!args || !args.length) {
this.outputHelp();
util.exit(1);
}
const [command] = args;
if (!_.includes(['list', 'path', 'clear', 'prune'], command)) {
unknownOption.call(this, `cache ${command}`, 'command');
}
if (command === 'list') {
debug('cache command %o', {
command,
size: opts.size
});
return cache.list(opts.size).catch({
code: 'ENOENT'
}, () => {
logger.always('No cached binary versions were found.');
process.exit(0);
}).catch(e => {
debug('cache list command failed with "%s"', e.message);
util.logErrorExit1(e);
});
}
cache[command]();
});
program.command('info').usage('[command]').description('Prints Cypress and system information').option('--dev', text('dev'), coerceFalse).action(opts => {
require('./exec/info').start(opts).then(util.exit).catch(util.logErrorExit1);
});
debug('cli starts with arguments %j', args);
util.printNodeOptions();
// if there are no arguments
if (args.length <= 2) {
debug('printing help');
program.help();
// exits
}
const firstCommand = args[2];
if (!_.includes(knownCommands, firstCommand)) {
debug('unknown command %s', firstCommand);
logger.error('Unknown command', `"${firstCommand}"`);
program.outputHelp();
return util.exit(1);
}
if (includesVersion(args)) {
// commander 2.11.0 changes behavior
// and now does not understand top level options
// .option('-v, --version').command('version')
// so we have to manually catch '-v, --version'
handleVersion(program);
}
debug('program parsing arguments');
return program.parse(args);
}
};
// @ts-ignore
if (!module.parent) {
logger.error('This CLI module should be required from another Node module');
logger.error('and not executed directly');
process.exit(-1);
}

98
CyLukTs/lukan/node_modules/cypress/lib/cypress.js generated vendored Normal file
View File

@ -0,0 +1,98 @@
"use strict";
// https://github.com/cypress-io/cypress/issues/316
const Promise = require('bluebird');
const tmp = Promise.promisifyAll(require('tmp'));
const fs = require('./fs');
const open = require('./exec/open');
const run = require('./exec/run');
const util = require('./util');
const cli = require('./cli');
const cypressModuleApi = {
/**
* Opens Cypress GUI
* @see https://on.cypress.io/module-api#cypress-open
*/
open(options = {}) {
options = util.normalizeModuleOptions(options);
return open.start(options);
},
/**
* Runs Cypress tests in the current project
* @see https://on.cypress.io/module-api#cypress-run
*/
run(options = {}) {
if (!run.isValidProject(options.project)) {
return Promise.reject(new Error(`Invalid project path parameter: ${options.project}`));
}
options = util.normalizeModuleOptions(options);
tmp.setGracefulCleanup();
return tmp.fileAsync().then(outputPath => {
options.outputPath = outputPath;
return run.start(options).then(failedTests => {
return fs.readJsonAsync(outputPath, {
throws: false
}).then(output => {
if (!output) {
return {
status: 'failed',
failures: failedTests,
message: 'Could not find Cypress test run results'
};
}
return output;
});
});
});
},
cli: {
/**
* Parses CLI arguments into an object that you can pass to "cypress.run"
* @example
* const cypress = require('cypress')
* const cli = ['cypress', 'run', '--browser', 'firefox']
* const options = await cypress.cli.parseRunArguments(cli)
* // options is {browser: 'firefox'}
* await cypress.run(options)
* @see https://on.cypress.io/module-api
*/
parseRunArguments(args) {
return cli.parseRunCommand(args);
}
},
/**
* Provides automatic code completion for configuration in many popular code editors.
* While it's not strictly necessary for Cypress to parse your configuration, we
* recommend wrapping your config object with `defineConfig()`
* @example
* module.exports = defineConfig({
* viewportWith: 400
* })
*
* @see ../types/cypress-npm-api.d.ts
* @param {Cypress.ConfigOptions} config
* @returns {Cypress.ConfigOptions} the configuration passed in parameter
*/
defineConfig(config) {
return config;
},
/**
* Provides automatic code completion for Component Frameworks Definitions.
* While it's not strictly necessary for Cypress to parse your configuration, we
* recommend wrapping your Component Framework Definition object with `defineComponentFramework()`
* @example
* module.exports = defineComponentFramework({
* type: 'cypress-ct-solid-js'
* // ...
* })
*
* @see ../types/cypress-npm-api.d.ts
* @param {Cypress.ThirdPartyComponentFrameworkDefinition} config
* @returns {Cypress.ThirdPartyComponentFrameworkDefinition} the configuration passed in parameter
*/
defineComponentFramework(config) {
return config;
}
};
module.exports = cypressModuleApi;

392
CyLukTs/lukan/node_modules/cypress/lib/errors.js generated vendored Normal file
View File

@ -0,0 +1,392 @@
"use strict";
const chalk = require('chalk');
const {
stripIndent,
stripIndents
} = require('common-tags');
const la = require('lazy-ass');
const is = require('check-more-types');
const util = require('./util');
const state = require('./tasks/state');
const docsUrl = 'https://on.cypress.io';
const requiredDependenciesUrl = `${docsUrl}/required-dependencies`;
const runDocumentationUrl = `${docsUrl}/cypress-run`;
// TODO it would be nice if all error objects could be enforced via types
// to only have description + solution properties
const hr = '----------';
const genericErrorSolution = stripIndent`
Search for an existing issue or open a GitHub issue at
${chalk.blue(util.issuesUrl)}
`;
// common errors Cypress application can encounter
const unknownError = {
description: 'Unknown Cypress CLI error',
solution: genericErrorSolution
};
const invalidRunProjectPath = {
description: 'Invalid --project path',
solution: stripIndent`
Please provide a valid project path.
Learn more about ${chalk.cyan('cypress run')} at:
${chalk.blue(runDocumentationUrl)}
`
};
const invalidOS = {
description: 'The Cypress App could not be installed. Your machine does not meet the operating system requirements.',
solution: stripIndent`
${chalk.blue('https://on.cypress.io/guides/getting-started/installing-cypress#system-requirements')}`
};
const failedDownload = {
description: 'The Cypress App could not be downloaded.',
solution: stripIndent`
Does your workplace require a proxy to be used to access the Internet? If so, you must configure the HTTP_PROXY environment variable before downloading Cypress. Read more: https://on.cypress.io/proxy-configuration
Otherwise, please check network connectivity and try again:`
};
const failedUnzip = {
description: 'The Cypress App could not be unzipped.',
solution: genericErrorSolution
};
const failedUnzipWindowsMaxPathLength = {
description: 'The Cypress App could not be unzipped.',
solution: `This is most likely because the maximum path length is being exceeded on your system.
Read here for solutions to this problem: https://on.cypress.io/win-max-path-length-error`
};
const missingApp = binaryDir => {
return {
description: `No version of Cypress is installed in: ${chalk.cyan(binaryDir)}`,
solution: stripIndent`
\nPlease reinstall Cypress by running: ${chalk.cyan('cypress install')}
`
};
};
const binaryNotExecutable = executable => {
return {
description: `Cypress cannot run because this binary file does not have executable permissions here:\n\n${executable}`,
solution: stripIndent`\n
Reasons this may happen:
- node was installed as 'root' or with 'sudo'
- the cypress npm package as 'root' or with 'sudo'
Please check that you have the appropriate user permissions.
You can also try clearing the cache with 'cypress cache clear' and reinstalling.
`
};
};
const notInstalledCI = executable => {
return {
description: 'The cypress npm package is installed, but the Cypress binary is missing.',
solution: stripIndent`\n
We expected the binary to be installed here: ${chalk.cyan(executable)}
Reasons it may be missing:
- You're caching 'node_modules' but are not caching this path: ${util.getCacheDir()}
- You ran 'npm install' at an earlier build step but did not persist: ${util.getCacheDir()}
Properly caching the binary will fix this error and avoid downloading and unzipping Cypress.
Alternatively, you can run 'cypress install' to download the binary again.
${chalk.blue('https://on.cypress.io/not-installed-ci-error')}
`
};
};
const nonZeroExitCodeXvfb = {
description: 'Xvfb exited with a non zero exit code.',
solution: stripIndent`
There was a problem spawning Xvfb.
This is likely a problem with your system, permissions, or installation of Xvfb.
`
};
const missingXvfb = {
description: 'Your system is missing the dependency: Xvfb',
solution: stripIndent`
Install Xvfb and run Cypress again.
Read our documentation on dependencies for more information:
${chalk.blue(requiredDependenciesUrl)}
If you are using Docker, we provide containers with all required dependencies installed.
`
};
const smokeTestFailure = (smokeTestCommand, timedOut) => {
return {
description: `Cypress verification ${timedOut ? 'timed out' : 'failed'}.`,
solution: stripIndent`
This command failed with the following output:
${smokeTestCommand}
`
};
};
const invalidSmokeTestDisplayError = {
code: 'INVALID_SMOKE_TEST_DISPLAY_ERROR',
description: 'Cypress verification failed.',
solution(msg) {
return stripIndent`
Cypress failed to start after spawning a new Xvfb server.
The error logs we received were:
${hr}
${msg}
${hr}
This may be due to a missing library or dependency. ${chalk.blue(requiredDependenciesUrl)}
Please refer to the error above for more detail.
`;
}
};
const missingDependency = {
description: 'Cypress failed to start.',
// this message is too Linux specific
solution: stripIndent`
This may be due to a missing library or dependency. ${chalk.blue(requiredDependenciesUrl)}
Please refer to the error below for more details.
`
};
const invalidCacheDirectory = {
description: 'Cypress cannot write to the cache directory due to file permissions',
solution: stripIndent`
See discussion and possible solutions at
${chalk.blue(util.getGitHubIssueUrl(1281))}
`
};
const versionMismatch = {
description: 'Installed version does not match package version.',
solution: 'Install Cypress and verify app again'
};
const incompatibleHeadlessFlags = {
description: '`--headed` and `--headless` cannot both be passed.',
solution: 'Either pass `--headed` or `--headless`, but not both.'
};
const solutionUnknown = stripIndent`
Please search Cypress documentation for possible solutions:
${chalk.blue(docsUrl)}
Check if there is a GitHub issue describing this crash:
${chalk.blue(util.issuesUrl)}
Consider opening a new issue.
`;
const unexpected = {
description: 'An unexpected error occurred while verifying the Cypress executable.',
solution: solutionUnknown
};
const invalidCypressEnv = {
description: chalk.red('The environment variable with the reserved name "CYPRESS_INTERNAL_ENV" is set.'),
solution: chalk.red('Unset the "CYPRESS_INTERNAL_ENV" environment variable and run Cypress again.'),
exitCode: 11
};
const invalidTestingType = {
description: 'Invalid testingType',
solution: `Please provide a valid testingType. Valid test types are ${chalk.cyan('\'e2e\'')} and ${chalk.cyan('\'component\'')}.`
};
const incompatibleTestTypeFlags = {
description: '`--e2e` and `--component` cannot both be passed.',
solution: 'Either pass `--e2e` or `--component`, but not both.'
};
const incompatibleTestingTypeAndFlag = {
description: 'Set a `testingType` and also passed `--e2e` or `--component` flags.',
solution: 'Either set `testingType` or pass a testing type flag, but not both.'
};
const invalidConfigFile = {
description: '`--config-file` cannot be false.',
solution: 'Either pass a relative path to a valid Cypress config file or remove this option.'
};
/**
* This error happens when CLI detects that the child Test Runner process
* was killed with a signal, like SIGBUS
* @see https://github.com/cypress-io/cypress/issues/5808
* @param {'close'|'event'} eventName Child close event name
* @param {string} signal Signal that closed the child process, like "SIGBUS"
*/
const childProcessKilled = (eventName, signal) => {
return {
description: `The Test Runner unexpectedly exited via a ${chalk.cyan(eventName)} event with signal ${chalk.cyan(signal)}`,
solution: solutionUnknown
};
};
const CYPRESS_RUN_BINARY = {
notValid: value => {
const properFormat = `**/${state.getPlatformExecutable()}`;
return {
description: `Could not run binary set by environment variable: CYPRESS_RUN_BINARY=${value}`,
solution: `Ensure the environment variable is a path to the Cypress binary, matching ${properFormat}`
};
}
};
function addPlatformInformation(info) {
return util.getPlatformInfo().then(platform => {
return {
...info,
platform
};
});
}
/**
* Given an error object (see the errors above), forms error message text with details,
* then resolves with Error instance you can throw or reject with.
* @param {object} errorObject
* @returns {Promise<Error>} resolves with an Error
* @example
```js
// inside a Promise with "resolve" and "reject"
const errorObject = childProcessKilled('exit', 'SIGKILL')
return getError(errorObject).then(reject)
```
*/
function getError(errorObject) {
return formErrorText(errorObject).then(errorMessage => {
const err = new Error(errorMessage);
err.known = true;
return err;
});
}
/**
* Forms nice error message with error and platform information,
* and if possible a way to solve it. Resolves with a string.
*/
function formErrorText(info, msg, prevMessage) {
return addPlatformInformation(info).then(obj => {
const formatted = [];
function add(msg) {
formatted.push(stripIndents(msg));
}
la(is.unemptyString(obj.description), 'expected error description to be text', obj.description);
// assuming that if there the solution is a function it will handle
// error message and (optional previous error message)
if (is.fn(obj.solution)) {
const text = obj.solution(msg, prevMessage);
la(is.unemptyString(text), 'expected solution to be text', text);
add(`
${obj.description}
${text}
`);
} else {
la(is.unemptyString(obj.solution), 'expected error solution to be text', obj.solution);
add(`
${obj.description}
${obj.solution}
`);
if (msg) {
add(`
${hr}
${msg}
`);
}
}
add(`
${hr}
${obj.platform}
`);
if (obj.footer) {
add(`
${hr}
${obj.footer}
`);
}
return formatted.join('\n\n');
});
}
const raise = info => {
return text => {
const err = new Error(text);
if (info.code) {
err.code = info.code;
}
err.known = true;
throw err;
};
};
const throwFormErrorText = info => {
return (msg, prevMessage) => {
return formErrorText(info, msg, prevMessage).then(raise(info));
};
};
/**
* Forms full error message with error and OS details, prints to the error output
* and then exits the process.
* @param {ErrorInformation} info Error information {description, solution}
* @example return exitWithError(errors.invalidCypressEnv)('foo')
*/
const exitWithError = info => {
return msg => {
return formErrorText(info, msg).then(text => {
// eslint-disable-next-line no-console
console.error(text);
process.exit(info.exitCode || 1);
});
};
};
module.exports = {
raise,
exitWithError,
// formError,
formErrorText,
throwFormErrorText,
getError,
hr,
errors: {
unknownError,
nonZeroExitCodeXvfb,
missingXvfb,
missingApp,
notInstalledCI,
missingDependency,
invalidOS,
invalidSmokeTestDisplayError,
versionMismatch,
binaryNotExecutable,
unexpected,
failedDownload,
failedUnzip,
failedUnzipWindowsMaxPathLength,
invalidCypressEnv,
invalidCacheDirectory,
CYPRESS_RUN_BINARY,
smokeTestFailure,
childProcessKilled,
incompatibleHeadlessFlags,
invalidRunProjectPath,
invalidTestingType,
incompatibleTestTypeFlags,
incompatibleTestingTypeAndFlag,
invalidConfigFile
}
};

92
CyLukTs/lukan/node_modules/cypress/lib/exec/info.js generated vendored Normal file
View File

@ -0,0 +1,92 @@
"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');
// color for numbers and show values
const g = chalk.green;
// color for paths
const p = chalk.cyan;
const red = chalk.red;
// 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 = obj => {
const masked = {
...obj
};
if (masked.CYPRESS_RECORD_KEY) {
masked.CYPRESS_RECORD_KEY = '<redacted>';
}
return masked;
};
methods.findCypressEnvironmentVariables = () => {
const isCyVariable = (val, key) => key.startsWith('CYPRESS_');
return _.pickBy(process.env, isCyVariable);
};
const formatCypressVariables = () => {
const vars = methods.findCypressEnvironmentVariables();
return maskSensitiveVariables(vars);
};
methods.start = async (options = {}) => {
const args = ['--mode=info'];
await spawn.start(args, {
dev: options.dev
});
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();
}
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));
});
}
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()));
console.log();
const osVersion = await util.getOsVersionAsync();
const buildInfo = util.pkgBuildInfo();
const isStable = buildInfo && buildInfo.stable;
console.log('Cypress Version: %s', g(util.pkgVersion()), isStable ? g('(stable)') : red('(pre-release)'));
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())));
if (!buildInfo) {
console.log();
console.log('This is the', red('development'), '(un-built) Cypress CLI.');
} else if (!isStable) {
console.log();
console.log('This is a', red('pre-release'), 'build of Cypress.');
console.log('Build info:');
console.log(' Commit SHA:', g(buildInfo.commitSha));
console.log(' Commit Branch:', g(buildInfo.commitBranch));
console.log(' Commit Date:', g(buildInfo.commitDate));
}
};
module.exports = methods;

90
CyLukTs/lukan/node_modules/cypress/lib/exec/open.js generated vendored Normal file
View File

@ -0,0 +1,90 @@
"use strict";
const debug = require('debug')('cypress:cli');
const util = require('../util');
const spawn = require('./spawn');
const verify = require('../tasks/verify');
const {
processTestingType,
checkConfigFile
} = require('./shared');
const {
exitWithError
} = require('../errors');
/**
* 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 processOpenOptions = (options = {}) => {
// In addition to setting the project directory, setting the project option
// here ultimately decides whether cypress is run in global mode or not.
// It's first based off whether it's installed globally by npm/yarn (-g).
// A global install can be overridden by the --project flag, putting Cypress
// in project mode. A non-global install can be overridden by the --global
// flag, putting it in global mode.
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) {
checkConfigFile(options);
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);
}
if (options.global) {
args.push('--global', options.global);
}
if (options.inspect) {
args.push('--inspect');
}
if (options.inspectBrk) {
args.push('--inspectBrk');
}
args.push(...processTestingType(options));
debug('opening from options %j', options);
debug('command line arguments %j', args);
return args;
};
module.exports = {
processOpenOptions,
start(options = {}) {
function open() {
try {
const args = processOpenOptions(options);
return spawn.start(args, {
dev: options.dev,
detached: Boolean(options.detached)
});
} catch (err) {
if (err.details) {
return exitWithError(err.details)();
}
throw err;
}
}
if (options.dev) {
return open();
}
return verify.start().then(open);
}
};

173
CyLukTs/lukan/node_modules/cypress/lib/exec/run.js generated vendored Normal file
View File

@ -0,0 +1,173 @@
"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,
checkConfigFile
} = 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.autoCancelAfterFailures || options.autoCancelAfterFailures === 0 || options.autoCancelAfterFailures === false) {
args.push('--auto-cancel-after-failures', options.autoCancelAfterFailures);
}
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) {
checkConfigFile(options);
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);
}
if (options.inspect) {
args.push('--inspect');
}
if (options.inspectBrk) {
args.push('--inspectBrk');
}
args.push(...processTestingType(options));
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() {
try {
const args = processRunOptions(options);
debug('run to spawn.start args %j', args);
return spawn.start(args, {
dev: options.dev
});
} catch (err) {
if (err.details) {
return exitWithError(err.details)();
}
throw err;
}
}
if (options.dev) {
return run();
}
return verify.start().then(run);
}
};

62
CyLukTs/lukan/node_modules/cypress/lib/exec/shared.js generated vendored Normal file
View File

@ -0,0 +1,62 @@
"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 = options => {
if (options.e2e && options.component) {
return throwInvalidOptionError(errors.incompatibleTestTypeFlags);
}
if (options.testingType && (options.component || options.e2e)) {
return throwInvalidOptionError(errors.incompatibleTestTypeFlags);
}
if (options.testingType === 'component' || options.component || options.ct) {
return ['--testing-type', 'component'];
}
if (options.testingType === 'e2e' || options.e2e) {
return ['--testing-type', 'e2e'];
}
if (options.testingType) {
return throwInvalidOptionError(errors.invalidTestingType);
}
return [];
};
/**
* Throws an error if configFile is string 'false' or boolean false
* @param {*} options
*/
const checkConfigFile = options => {
// CLI will parse as string, module API can pass in boolean
if (options.configFile === 'false' || options.configFile === false) {
throwInvalidOptionError(errors.invalidConfigFile);
}
};
module.exports = {
throwInvalidOptionError,
processTestingType,
checkConfigFile
};

289
CyLukTs/lukan/node_modules/cypress/lib/exec/spawn.js generated vendored Normal file
View File

@ -0,0 +1,289 @@
"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-/;
// Chromium (which Electron uses) always makes several attempts to connect to the system dbus.
// This works fine in most desktop environments, but in a docker container, there is no dbus service
// and Chromium emits several error lines, similar to these:
// [1957:0406/160550.146820:ERROR:bus.cc(392)] Failed to connect to the bus: Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory
// [1957:0406/160550.147994:ERROR:bus.cc(392)] Failed to connect to the bus: Address does not contain a colon
// These warnings are absolutely harmless. Failure to connect to dbus means that electron won't be able to access the user's
// credential wallet (none exists in a docker container) and won't show up in the system tray (again, none exists).
// Failure to connect is expected and normal here, but users frequently misidentify these errors as the cause of their problems.
// https://github.com/cypress-io/cypress/issues/19299
const isDbusWarning = /Failed to connect to the bus:/;
// Electron began logging these on self-signed certs with 17.0.0-alpha.4.
// Once this is fixed upstream this regex can be removed: https://github.com/electron/electron/issues/34583
// Sample:
// [3801:0606/152837.383892:ERROR:cert_verify_proc_builtin.cc(681)] CertVerifyProcBuiltin for www.googletagmanager.com failed:
// ----- Certificate i=0 (OU=Cypress Proxy Server Certificate,O=Cypress Proxy CA,L=Internet,ST=Internet,C=Internet,CN=www.googletagmanager.com) -----
// ERROR: No matching issuer found
const isCertVerifyProcBuiltin = /(^\[.*ERROR:cert_verify_proc_builtin\.cc|^----- Certificate i=0 \(OU=Cypress Proxy|^ERROR: No matching issuer found$)/;
// Electron logs a benign warning about WebSwapCGLLayer on MacOS v12 and Electron v18 due to a naming collision in shared libraries.
// Once this is fixed upstream this regex can be removed: https://github.com/electron/electron/issues/33685
// Sample:
// objc[60540]: Class WebSwapCGLLayer is implemented in both /System/Library/Frameworks/WebKit.framework/Versions/A/Frameworks/WebCore.framework/Versions/A/Frameworks/libANGLE-shared.dylib (0x7ffa5a006318) and /{path/to/app}/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libGLESv2.dylib (0x10f8a89c8). One of the two will be used. Which one is undefined.
const isMacOSElectronWebSwapCGLLayerWarning = /^objc\[\d+\]: Class WebSwapCGLLayer is implemented in both.*Which one is undefined\./;
const GARBAGE_WARNINGS = [isXlibOrLibudevRe, isHighSierraWarningRe, isRenderWorkerRe, isDbusWarning, isCertVerifyProcBuiltin, isMacOSElectronWebSwapCGLLayerWarning];
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(), '--userNodePath', process.execPath, '--userNodeVersion', process.versions.node];
_.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');
let startScriptPath;
if (options.dev) {
executable = 'node';
// if we're in dev then reset
// the launch cmd to be 'npm run dev'
startScriptPath = 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
/**
* @type {import('child_process').ForkOptions}
*/
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.
startScriptPath = path.join(state.getBinaryPkgPath(path.dirname(executable)), '..', 'index.js');
} 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];
}
if (startScriptPath) {
args.unshift(startScriptPath);
}
if (process.env.CYPRESS_INTERNAL_DEV_DEBUG) {
args.unshift(process.env.CYPRESS_INTERNAL_DEV_DEBUG);
}
debug('spawn args %o %o', args, _.omit(stdioOptions, 'env'));
debug('spawning Cypress with executable: %s', executable);
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);
}
};

View File

@ -0,0 +1,53 @@
"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 buildInfo = util.pkgBuildInfo();
let packageVersion = util.pkgVersion();
if (!buildInfo) packageVersion += ' (development)';else if (!buildInfo.stable) packageVersion += ' (pre-release)';
const versions = {
package: packageVersion,
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
};

94
CyLukTs/lukan/node_modules/cypress/lib/exec/xvfb.js generated vendored Normal file
View File

@ -0,0 +1,94 @@
"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 = {
displayNum: process.env.XVFB_DISPLAY_NUM,
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);
}
};

4
CyLukTs/lukan/node_modules/cypress/lib/fs.js generated vendored Normal file
View File

@ -0,0 +1,4 @@
"use strict";
const Promise = require('bluebird');
module.exports = Promise.promisifyAll(require('fs-extra'));

53
CyLukTs/lukan/node_modules/cypress/lib/logger.js generated vendored Normal file
View File

@ -0,0 +1,53 @@
"use strict";
const chalk = require('chalk');
let logs = [];
const logLevel = () => {
return process.env.npm_config_loglevel || 'notice';
};
const error = (...messages) => {
logs.push(messages.join(' '));
console.log(chalk.red(...messages)); // eslint-disable-line no-console
};
const warn = (...messages) => {
if (logLevel() === 'silent') return;
logs.push(messages.join(' '));
console.log(chalk.yellow(...messages)); // eslint-disable-line no-console
};
const log = (...messages) => {
if (logLevel() === 'silent' || logLevel() === 'warn') return;
logs.push(messages.join(' '));
console.log(...messages); // eslint-disable-line no-console
};
const always = (...messages) => {
logs.push(messages.join(' '));
console.log(...messages); // eslint-disable-line no-console
};
// splits long text into lines and calls log()
// on each one to allow easy unit testing for specific message
const logLines = text => {
const lines = text.split('\n');
for (const line of lines) {
log(line);
}
};
const print = () => {
return logs.join('\n');
};
const reset = () => {
logs = [];
};
module.exports = {
log,
warn,
error,
always,
logLines,
print,
reset,
logLevel
};

132
CyLukTs/lukan/node_modules/cypress/lib/tasks/cache.js generated vendored Normal file
View File

@ -0,0 +1,132 @@
"use strict";
const state = require('./state');
const logger = require('../logger');
const fs = require('../fs');
const util = require('../util');
const {
join
} = require('path');
const Table = require('cli-table3');
const dayjs = require('dayjs');
const relativeTime = require('dayjs/plugin/relativeTime');
const chalk = require('chalk');
const _ = require('lodash');
const getFolderSize = require('./get-folder-size');
const Bluebird = require('bluebird');
dayjs.extend(relativeTime);
// output colors for the table
const colors = {
titles: chalk.white,
dates: chalk.cyan,
values: chalk.green,
size: chalk.gray
};
const logCachePath = () => {
logger.always(state.getCacheDir());
return undefined;
};
const clear = () => {
return fs.removeAsync(state.getCacheDir());
};
const prune = () => {
const cacheDir = state.getCacheDir();
const checkedInBinaryVersion = util.pkgVersion();
let deletedBinary = false;
return fs.readdirAsync(cacheDir).then(versions => {
return Bluebird.all(versions.map(version => {
if (version !== checkedInBinaryVersion) {
deletedBinary = true;
const versionDir = join(cacheDir, version);
return fs.removeAsync(versionDir);
}
}));
}).then(() => {
if (deletedBinary) {
logger.always(`Deleted all binary caches except for the ${checkedInBinaryVersion} binary cache.`);
} else {
logger.always(`No binary caches found to prune.`);
}
}).catch({
code: 'ENOENT'
}, () => {
logger.always(`No Cypress cache was found at ${cacheDir}. Nothing to prune.`);
});
};
const fileSizeInMB = size => {
return `${(size / 1024 / 1024).toFixed(1)}MB`;
};
/**
* Collects all cached versions, finds when each was used
* and prints a table with results to the terminal
*/
const list = showSize => {
return getCachedVersions(showSize).then(binaries => {
const head = [colors.titles('version'), colors.titles('last used')];
if (showSize) {
head.push(colors.titles('size'));
}
const table = new Table({
head
});
binaries.forEach(binary => {
const versionString = colors.values(binary.version);
const lastUsed = binary.accessed ? colors.dates(binary.accessed) : 'unknown';
const row = [versionString, lastUsed];
if (showSize) {
const size = colors.size(fileSizeInMB(binary.size));
row.push(size);
}
return table.push(row);
});
logger.always(table.toString());
});
};
const getCachedVersions = showSize => {
const cacheDir = state.getCacheDir();
return fs.readdirAsync(cacheDir).filter(util.isSemver).map(version => {
return {
version,
folderPath: join(cacheDir, version)
};
}).mapSeries(binary => {
// last access time on the folder is different from last access time
// on the Cypress binary
const binaryDir = state.getBinaryDir(binary.version);
const executable = state.getPathToExecutable(binaryDir);
return fs.statAsync(executable).then(stat => {
const lastAccessedTime = _.get(stat, 'atime');
if (!lastAccessedTime) {
// the test runner has never been opened
// or could be a test simulating missing timestamp
return binary;
}
const accessed = dayjs(lastAccessedTime).fromNow();
binary.accessed = accessed;
return binary;
}, e => {
// could not find the binary or gets its stats
return binary;
});
}).mapSeries(binary => {
if (showSize) {
const binaryDir = state.getBinaryDir(binary.version);
return getFolderSize(binaryDir).then(size => {
return {
...binary,
size
};
});
}
return binary;
});
};
module.exports = {
path: logCachePath,
clear,
prune,
list,
getCachedVersions
};

View File

@ -0,0 +1,319 @@
"use strict";
const la = require('lazy-ass');
const is = require('check-more-types');
const os = require('os');
const url = require('url');
const path = require('path');
const debug = require('debug')('cypress:cli');
const request = require('@cypress/request');
const Promise = require('bluebird');
const requestProgress = require('request-progress');
const {
stripIndent
} = require('common-tags');
const getProxyForUrl = require('proxy-from-env').getProxyForUrl;
const {
throwFormErrorText,
errors
} = require('../errors');
const fs = require('../fs');
const util = require('../util');
const defaultBaseUrl = 'https://download.cypress.io/';
const defaultMaxRedirects = 10;
const getProxyForUrlWithNpmConfig = url => {
return getProxyForUrl(url) || process.env.npm_config_https_proxy || process.env.npm_config_proxy || null;
};
const getBaseUrl = () => {
if (util.getEnv('CYPRESS_DOWNLOAD_MIRROR')) {
let baseUrl = util.getEnv('CYPRESS_DOWNLOAD_MIRROR');
if (!baseUrl.endsWith('/')) {
baseUrl += '/';
}
return baseUrl;
}
return defaultBaseUrl;
};
const getCA = () => {
return new Promise(resolve => {
if (process.env.npm_config_cafile) {
fs.readFile(process.env.npm_config_cafile, 'utf8').then(cafileContent => {
resolve(cafileContent);
}).catch(() => {
resolve();
});
} else if (process.env.npm_config_ca) {
resolve(process.env.npm_config_ca);
} else {
resolve();
}
});
};
const prepend = (arch, urlPath, version) => {
const endpoint = url.resolve(getBaseUrl(), urlPath);
const platform = os.platform();
const pathTemplate = util.getEnv('CYPRESS_DOWNLOAD_PATH_TEMPLATE', true);
return pathTemplate ? pathTemplate.replace(/\\?\$\{endpoint\}/g, endpoint).replace(/\\?\$\{platform\}/g, platform).replace(/\\?\$\{arch\}/g, arch).replace(/\\?\$\{version\}/g, version) : `${endpoint}?platform=${platform}&arch=${arch}`;
};
const getUrl = (arch, version) => {
if (is.url(version)) {
debug('version is already an url', version);
return version;
}
const urlPath = version ? `desktop/${version}` : 'desktop';
return prepend(arch, urlPath, version);
};
const statusMessage = err => {
return err.statusCode ? [err.statusCode, err.statusMessage].join(' - ') : err.toString();
};
const prettyDownloadErr = (err, url) => {
const msg = stripIndent`
URL: ${url}
${statusMessage(err)}
`;
debug(msg);
return throwFormErrorText(errors.failedDownload)(msg);
};
/**
* Checks checksum and file size for the given file. Allows both
* values or just one of them to be checked.
*/
const verifyDownloadedFile = (filename, expectedSize, expectedChecksum) => {
if (expectedSize && expectedChecksum) {
debug('verifying checksum and file size');
return Promise.join(util.getFileChecksum(filename), util.getFileSize(filename), (checksum, filesize) => {
if (checksum === expectedChecksum && filesize === expectedSize) {
debug('downloaded file has the expected checksum and size ✅');
return;
}
debug('raising error: checksum or file size mismatch');
const text = stripIndent`
Corrupted download
Expected downloaded file to have checksum: ${expectedChecksum}
Computed checksum: ${checksum}
Expected downloaded file to have size: ${expectedSize}
Computed size: ${filesize}
`;
debug(text);
throw new Error(text);
});
}
if (expectedChecksum) {
debug('only checking expected file checksum %d', expectedChecksum);
return util.getFileChecksum(filename).then(checksum => {
if (checksum === expectedChecksum) {
debug('downloaded file has the expected checksum ✅');
return;
}
debug('raising error: file checksum mismatch');
const text = stripIndent`
Corrupted download
Expected downloaded file to have checksum: ${expectedChecksum}
Computed checksum: ${checksum}
`;
throw new Error(text);
});
}
if (expectedSize) {
// maybe we don't have a checksum, but at least CDN returns content length
// which we can check against the file size
debug('only checking expected file size %d', expectedSize);
return util.getFileSize(filename).then(filesize => {
if (filesize === expectedSize) {
debug('downloaded file has the expected size ✅');
return;
}
debug('raising error: file size mismatch');
const text = stripIndent`
Corrupted download
Expected downloaded file to have size: ${expectedSize}
Computed size: ${filesize}
`;
throw new Error(text);
});
}
debug('downloaded file lacks checksum or size to verify');
return Promise.resolve();
};
// downloads from given url
// return an object with
// {filename: ..., downloaded: true}
const downloadFromUrl = ({
url,
downloadDestination,
progress,
ca,
version,
redirectTTL = defaultMaxRedirects
}) => {
if (redirectTTL <= 0) {
return Promise.reject(new Error(stripIndent`
Failed downloading the Cypress binary.
There were too many redirects. The default allowance is ${defaultMaxRedirects}.
Maybe you got stuck in a redirect loop?
`));
}
return new Promise((resolve, reject) => {
const proxy = getProxyForUrlWithNpmConfig(url);
debug('Downloading package', {
url,
proxy,
downloadDestination
});
if (ca) {
debug('using custom CA details from npm config');
}
const reqOptions = {
uri: url,
...(proxy ? {
proxy
} : {}),
...(ca ? {
agentOptions: {
ca
}
} : {}),
method: 'GET',
followRedirect: false
};
const req = request(reqOptions);
// closure
let started = null;
let expectedSize;
let expectedChecksum;
requestProgress(req, {
throttle: progress.throttle
}).on('response', response => {
// we have computed checksum and filesize during test runner binary build
// and have set it on the S3 object as user meta data, available via
// these custom headers "x-amz-meta-..."
// see https://github.com/cypress-io/cypress/pull/4092
expectedSize = response.headers['x-amz-meta-size'] || response.headers['content-length'];
expectedChecksum = response.headers['x-amz-meta-checksum'];
if (expectedChecksum) {
debug('expected checksum %s', expectedChecksum);
}
if (expectedSize) {
// convert from string (all Amazon custom headers are strings)
expectedSize = Number(expectedSize);
debug('expected file size %d', expectedSize);
}
// start counting now once we've gotten
// response headers
started = new Date();
if (/^3/.test(response.statusCode)) {
const redirectVersion = response.headers['x-version'];
const redirectUrl = response.headers.location;
debug('redirect version:', redirectVersion);
debug('redirect url:', redirectUrl);
downloadFromUrl({
url: redirectUrl,
progress,
ca,
downloadDestination,
version: redirectVersion,
redirectTTL: redirectTTL - 1
}).then(resolve).catch(reject);
// if our status code does not start with 200
} else if (!/^2/.test(response.statusCode)) {
debug('response code %d', response.statusCode);
const err = new Error(stripIndent`
Failed downloading the Cypress binary.
Response code: ${response.statusCode}
Response message: ${response.statusMessage}
`);
reject(err);
// status codes here are all 2xx
} else {
// We only enable this pipe connection when we know we've got a successful return
// and handle the completion with verify and resolve
// there was a possible race condition between end of request and close of writeStream
// that is made ordered with this Promise.all
Promise.all([new Promise(r => {
return response.pipe(fs.createWriteStream(downloadDestination).on('close', r));
}), new Promise(r => response.on('end', r))]).then(() => {
debug('downloading finished');
verifyDownloadedFile(downloadDestination, expectedSize, expectedChecksum).then(() => debug('verified')).then(() => resolve(version)).catch(reject);
});
}
}).on('error', e => {
if (e.code === 'ECONNRESET') return; // sometimes proxies give ECONNRESET but we don't care
reject(e);
}).on('progress', state => {
// total time we've elapsed
// starting on our first progress notification
const elapsed = new Date() - started;
// request-progress sends a value between 0 and 1
const percentage = util.convertPercentToPercentage(state.percent);
const eta = util.calculateEta(percentage, elapsed);
// send up our percent and seconds remaining
progress.onProgress(percentage, util.secsRemaining(eta));
});
});
};
/**
* Download Cypress.zip from external versionUrl to local file.
* @param [string] version Could be "3.3.0" or full URL
* @param [string] downloadDestination Local filename to save as
*/
const start = async opts => {
let {
version,
downloadDestination,
progress,
redirectTTL
} = opts;
if (!downloadDestination) {
la(is.unemptyString(downloadDestination), 'missing download dir', opts);
}
if (!progress) {
progress = {
onProgress: () => {
return {};
}
};
}
const arch = await util.getRealArch();
const versionUrl = getUrl(arch, version);
progress.throttle = 100;
debug('needed Cypress version: %s', version);
debug('source url %s', versionUrl);
debug(`downloading cypress.zip to "${downloadDestination}"`);
// ensure download dir exists
return fs.ensureDirAsync(path.dirname(downloadDestination)).then(() => {
return getCA();
}).then(ca => {
return downloadFromUrl({
url: versionUrl,
downloadDestination,
progress,
ca,
version,
...(redirectTTL ? {
redirectTTL
} : {})
});
}).catch(err => {
return prettyDownloadErr(err, versionUrl);
});
};
module.exports = {
start,
getUrl,
getProxyForUrlWithNpmConfig,
getCA
};

View File

@ -0,0 +1,33 @@
"use strict";
const fs = require('../fs');
const {
join
} = require('path');
const Bluebird = require('bluebird');
/**
* Get the size of a folder or a file.
*
* This function returns the actual file size of the folder (size), not the allocated space on disk (size on disk).
* For more details between the difference, check this link:
* https://www.howtogeek.com/180369/why-is-there-a-big-difference-between-size-and-size-on-disk/
*
* @param {string} path path to the file or the folder.
*/
async function getSize(path) {
const stat = await fs.lstat(path);
if (stat.isDirectory()) {
const list = await fs.readdir(path);
return Bluebird.resolve(list).reduce(async (prev, curr) => {
const currPath = join(path, curr);
const s = await fs.lstat(currPath);
if (s.isDirectory()) {
return prev + (await getSize(currPath));
}
return prev + s.size;
}, 0);
}
return stat.size;
}
module.exports = getSize;

360
CyLukTs/lukan/node_modules/cypress/lib/tasks/install.js generated vendored Normal file
View File

@ -0,0 +1,360 @@
"use strict";
const _ = require('lodash');
const os = require('os');
const path = require('path');
const chalk = require('chalk');
const debug = require('debug')('cypress:cli');
const {
Listr
} = require('listr2');
const Promise = require('bluebird');
const logSymbols = require('log-symbols');
const {
stripIndent
} = require('common-tags');
const fs = require('../fs');
const download = require('./download');
const util = require('../util');
const state = require('./state');
const unzip = require('./unzip');
const logger = require('../logger');
const {
throwFormErrorText,
errors
} = require('../errors');
const verbose = require('../VerboseRenderer');
const {
buildInfo,
version
} = require('../../package.json');
function _getBinaryUrlFromBuildInfo(arch, {
commitSha,
commitBranch
}) {
return `https://cdn.cypress.io/beta/binary/${version}/${os.platform()}-${arch}/${commitBranch}-${commitSha}/cypress.zip`;
}
const alreadyInstalledMsg = () => {
if (!util.isPostInstall()) {
logger.log(stripIndent`
Skipping installation:
Pass the ${chalk.yellow('--force')} option if you'd like to reinstall anyway.
`);
}
};
const displayCompletionMsg = () => {
// check here to see if we are globally installed
if (util.isInstalledGlobally()) {
// if we are display a warning
logger.log();
logger.warn(stripIndent`
${logSymbols.warning} Warning: 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:
- ${chalk.cyan('npm uninstall -g cypress')}
- ${chalk.cyan('npm install --save-dev cypress')}
`);
return;
}
logger.log();
logger.log('You can now open Cypress by running:', chalk.cyan(path.join('node_modules', '.bin', 'cypress'), 'open'));
logger.log();
logger.log(chalk.grey('https://on.cypress.io/installing-cypress'));
logger.log();
};
const downloadAndUnzip = ({
version,
installDir,
downloadDir
}) => {
const progress = {
throttle: 100,
onProgress: null
};
const downloadDestination = path.join(downloadDir, `cypress-${process.pid}.zip`);
const rendererOptions = getRendererOptions();
// let the user know what version of cypress we're downloading!
logger.log(`Installing Cypress ${chalk.gray(`(version: ${version})`)}`);
logger.log();
const tasks = new Listr([{
options: {
title: util.titleize('Downloading Cypress')
},
task: (ctx, task) => {
// as our download progresses indicate the status
progress.onProgress = progessify(task, 'Downloading Cypress');
return download.start({
version,
downloadDestination,
progress
}).then(redirectVersion => {
if (redirectVersion) version = redirectVersion;
debug(`finished downloading file: ${downloadDestination}`);
}).then(() => {
// save the download destination for unzipping
util.setTaskTitle(task, util.titleize(chalk.green('Downloaded Cypress')), rendererOptions.renderer);
});
}
}, unzipTask({
progress,
zipFilePath: downloadDestination,
installDir,
rendererOptions
}), {
options: {
title: util.titleize('Finishing Installation')
},
task: (ctx, task) => {
const cleanup = () => {
debug('removing zip file %s', downloadDestination);
return fs.removeAsync(downloadDestination);
};
return cleanup().then(() => {
debug('finished installation in', installDir);
util.setTaskTitle(task, util.titleize(chalk.green('Finished Installation'), chalk.gray(installDir)), rendererOptions.renderer);
});
}
}], {
rendererOptions
});
// start the tasks!
return Promise.resolve(tasks.run());
};
const validateOS = () => {
return util.getPlatformInfo().then(platformInfo => {
return platformInfo.match(/(win32-x64|linux-x64|linux-arm64|darwin-x64|darwin-arm64)/);
});
};
/**
* Returns the version to install - either a string like `1.2.3` to be fetched
* from the download server or a file path or HTTP URL.
*/
function getVersionOverride({
arch,
envVarVersion,
buildInfo
}) {
// let this environment variable reset the binary version we need
if (envVarVersion) {
return envVarVersion;
}
if (buildInfo && !buildInfo.stable) {
logger.log(chalk.yellow(stripIndent`
${logSymbols.warning} Warning: You are installing a pre-release build of Cypress.
Bugs may be present which do not exist in production builds.
This build was created from:
* Commit SHA: ${buildInfo.commitSha}
* Commit Branch: ${buildInfo.commitBranch}
* Commit Timestamp: ${buildInfo.commitDate}
`));
logger.log();
return _getBinaryUrlFromBuildInfo(arch, buildInfo);
}
}
function getEnvVarVersion() {
if (!util.getEnv('CYPRESS_INSTALL_BINARY')) return;
// because passed file paths are often double quoted
// and might have extra whitespace around, be robust and trim the string
const trimAndRemoveDoubleQuotes = true;
const envVarVersion = util.getEnv('CYPRESS_INSTALL_BINARY', trimAndRemoveDoubleQuotes);
debug('using environment variable CYPRESS_INSTALL_BINARY "%s"', envVarVersion);
return envVarVersion;
}
const start = async (options = {}) => {
debug('installing with options %j', options);
const envVarVersion = getEnvVarVersion();
if (envVarVersion === '0') {
debug('environment variable CYPRESS_INSTALL_BINARY = 0, skipping install');
logger.log(stripIndent`
${chalk.yellow('Note:')} Skipping binary installation: Environment variable CYPRESS_INSTALL_BINARY = 0.`);
logger.log();
return;
}
_.defaults(options, {
force: false,
buildInfo
});
if (util.getEnv('CYPRESS_CACHE_FOLDER')) {
const envCache = util.getEnv('CYPRESS_CACHE_FOLDER');
logger.log(stripIndent`
${chalk.yellow('Note:')} Overriding Cypress cache directory to: ${chalk.cyan(envCache)}
Previous installs of Cypress may not be found.
`);
logger.log();
}
const pkgVersion = util.pkgVersion();
const arch = await util.getRealArch();
const versionOverride = getVersionOverride({
arch,
envVarVersion,
buildInfo: options.buildInfo
});
const versionToInstall = versionOverride || pkgVersion;
debug('version in package.json is %s, version to install is %s', pkgVersion, versionToInstall);
const installDir = state.getVersionDir(pkgVersion, options.buildInfo);
const cacheDir = state.getCacheDir();
const binaryDir = state.getBinaryDir(pkgVersion);
if (!(await validateOS())) {
return throwFormErrorText(errors.invalidOS)();
}
await fs.ensureDirAsync(cacheDir).catch({
code: 'EACCES'
}, err => {
return throwFormErrorText(errors.invalidCacheDirectory)(stripIndent`
Failed to access ${chalk.cyan(cacheDir)}:
${err.message}
`);
});
const binaryPkg = await state.getBinaryPkgAsync(binaryDir);
const binaryVersion = await state.getBinaryPkgVersion(binaryPkg);
const shouldInstall = () => {
if (!binaryVersion) {
debug('no binary installed under cli version');
return true;
}
logger.log();
logger.log(stripIndent`
Cypress ${chalk.green(binaryVersion)} is installed in ${chalk.cyan(installDir)}
`);
logger.log();
if (options.force) {
debug('performing force install over existing binary');
return true;
}
if (binaryVersion === versionToInstall || !util.isSemver(versionToInstall)) {
// our version matches, tell the user this is a noop
alreadyInstalledMsg();
return false;
}
return true;
};
// noop if we've been told not to download
if (!shouldInstall()) {
return debug('Not downloading or installing binary');
}
if (envVarVersion) {
logger.log(chalk.yellow(stripIndent`
${logSymbols.warning} Warning: Forcing a binary version different than the default.
The CLI expected to install version: ${chalk.green(pkgVersion)}
Instead we will install version: ${chalk.green(versionToInstall)}
These versions may not work properly together.
`));
logger.log();
}
const getLocalFilePath = async () => {
// see if version supplied is a path to a binary
if (await fs.pathExistsAsync(versionToInstall)) {
return path.extname(versionToInstall) === '.zip' ? versionToInstall : false;
}
const possibleFile = util.formAbsolutePath(versionToInstall);
debug('checking local file', possibleFile, 'cwd', process.cwd());
// if this exists return the path to it
// else false
if ((await fs.pathExistsAsync(possibleFile)) && path.extname(possibleFile) === '.zip') {
return possibleFile;
}
return false;
};
const pathToLocalFile = await getLocalFilePath();
if (pathToLocalFile) {
const absolutePath = path.resolve(versionToInstall);
debug('found local file at', absolutePath);
debug('skipping download');
const rendererOptions = getRendererOptions();
return new Listr([unzipTask({
progress: {
throttle: 100,
onProgress: null
},
zipFilePath: absolutePath,
installDir,
rendererOptions
})], {
rendererOptions
}).run();
}
if (options.force) {
debug('Cypress already installed at', installDir);
debug('but the installation was forced');
}
debug('preparing to download and unzip version ', versionToInstall, 'to path', installDir);
const downloadDir = os.tmpdir();
await downloadAndUnzip({
version: versionToInstall,
installDir,
downloadDir
});
// delay 1 sec for UX, unless we are testing
await Promise.delay(1000);
displayCompletionMsg();
};
module.exports = {
start,
_getBinaryUrlFromBuildInfo
};
const unzipTask = ({
zipFilePath,
installDir,
progress,
rendererOptions
}) => {
return {
options: {
title: util.titleize('Unzipping Cypress')
},
task: (ctx, task) => {
// as our unzip progresses indicate the status
progress.onProgress = progessify(task, 'Unzipping Cypress');
return unzip.start({
zipFilePath,
installDir,
progress
}).then(() => {
util.setTaskTitle(task, util.titleize(chalk.green('Unzipped Cypress')), rendererOptions.renderer);
});
}
};
};
const progessify = (task, title) => {
// return higher order function
return (percentComplete, remaining) => {
percentComplete = chalk.white(` ${percentComplete}%`);
// pluralize seconds remaining
remaining = chalk.gray(`${remaining}s`);
util.setTaskTitle(task, util.titleize(title, percentComplete, remaining), getRendererOptions().renderer);
};
};
// if we are running in CI then use
// the verbose renderer else use
// the default
const getRendererOptions = () => {
let renderer = util.isCi() ? verbose : 'default';
if (logger.logLevel() === 'silent') {
renderer = 'silent';
}
return {
renderer
};
};

185
CyLukTs/lukan/node_modules/cypress/lib/tasks/state.js generated vendored Normal file
View File

@ -0,0 +1,185 @@
"use strict";
const _ = require('lodash');
const os = require('os');
const path = require('path');
const untildify = require('untildify');
const debug = require('debug')('cypress:cli');
const fs = require('../fs');
const util = require('../util');
const getPlatformExecutable = () => {
const platform = os.platform();
switch (platform) {
case 'darwin':
return 'Contents/MacOS/Cypress';
case 'linux':
return 'Cypress';
case 'win32':
return 'Cypress.exe';
// TODO handle this error using our standard
default:
throw new Error(`Platform: "${platform}" is not supported.`);
}
};
const getPlatFormBinaryFolder = () => {
const platform = os.platform();
switch (platform) {
case 'darwin':
return 'Cypress.app';
case 'linux':
return 'Cypress';
case 'win32':
return 'Cypress';
// TODO handle this error using our standard
default:
throw new Error(`Platform: "${platform}" is not supported.`);
}
};
const getBinaryPkgPath = binaryDir => {
const platform = os.platform();
switch (platform) {
case 'darwin':
return path.join(binaryDir, 'Contents', 'Resources', 'app', 'package.json');
case 'linux':
return path.join(binaryDir, 'resources', 'app', 'package.json');
case 'win32':
return path.join(binaryDir, 'resources', 'app', 'package.json');
// TODO handle this error using our standard
default:
throw new Error(`Platform: "${platform}" is not supported.`);
}
};
/**
* Get path to binary directory
*/
const getBinaryDir = (version = util.pkgVersion()) => {
return path.join(getVersionDir(version), getPlatFormBinaryFolder());
};
const getVersionDir = (version = util.pkgVersion(), buildInfo = util.pkgBuildInfo()) => {
if (buildInfo && !buildInfo.stable) {
version = ['beta', version, buildInfo.commitBranch, buildInfo.commitSha.slice(0, 8)].join('-');
}
return path.join(getCacheDir(), version);
};
/**
* When executing "npm postinstall" hook, the working directory is set to
* "<current folder>/node_modules/cypress", which can be surprising when using relative paths.
*/
const isInstallingFromPostinstallHook = () => {
// individual folders
const cwdFolders = process.cwd().split(path.sep);
const length = cwdFolders.length;
return cwdFolders[length - 2] === 'node_modules' && cwdFolders[length - 1] === 'cypress';
};
const getCacheDir = () => {
let cache_directory = util.getCacheDir();
if (util.getEnv('CYPRESS_CACHE_FOLDER')) {
const envVarCacheDir = untildify(util.getEnv('CYPRESS_CACHE_FOLDER'));
debug('using environment variable CYPRESS_CACHE_FOLDER %s', envVarCacheDir);
if (!path.isAbsolute(envVarCacheDir) && isInstallingFromPostinstallHook()) {
const packageRootFolder = path.join('..', '..', envVarCacheDir);
cache_directory = path.resolve(packageRootFolder);
debug('installing from postinstall hook, original root folder is %s', packageRootFolder);
debug('and resolved cache directory is %s', cache_directory);
} else {
cache_directory = path.resolve(envVarCacheDir);
}
}
return cache_directory;
};
const parseRealPlatformBinaryFolderAsync = binaryPath => {
return fs.realpathAsync(binaryPath).then(realPath => {
debug('CYPRESS_RUN_BINARY has realpath:', realPath);
if (!realPath.toString().endsWith(getPlatformExecutable())) {
return false;
}
if (os.platform() === 'darwin') {
return path.resolve(realPath, '..', '..', '..');
}
return path.resolve(realPath, '..');
});
};
const getDistDir = () => {
return path.join(__dirname, '..', '..', 'dist');
};
/**
* Returns full filename to the file that keeps the Test Runner verification state as JSON text.
* Note: the binary state file will be stored one level up from the given binary folder.
* @param {string} binaryDir - full path to the folder holding the binary.
*/
const getBinaryStatePath = binaryDir => {
return path.join(binaryDir, '..', 'binary_state.json');
};
const getBinaryStateContentsAsync = binaryDir => {
const fullPath = getBinaryStatePath(binaryDir);
return fs.readJsonAsync(fullPath).catch({
code: 'ENOENT'
}, SyntaxError, () => {
debug('could not read binary_state.json file at "%s"', fullPath);
return {};
});
};
const getBinaryVerifiedAsync = binaryDir => {
return getBinaryStateContentsAsync(binaryDir).tap(debug).get('verified');
};
const clearBinaryStateAsync = binaryDir => {
return fs.removeAsync(getBinaryStatePath(binaryDir));
};
/**
* Writes the new binary status.
* @param {boolean} verified The new test runner state after smoke test
* @param {string} binaryDir Folder holding the binary
* @returns {Promise<void>} returns a promise
*/
const writeBinaryVerifiedAsync = (verified, binaryDir) => {
return getBinaryStateContentsAsync(binaryDir).then(contents => {
return fs.outputJsonAsync(getBinaryStatePath(binaryDir), _.extend(contents, {
verified
}), {
spaces: 2
});
});
};
const getPathToExecutable = binaryDir => {
return path.join(binaryDir, getPlatformExecutable());
};
/**
* Resolves with an object read from the binary app package.json file.
* If the file does not exist resolves with null
*/
const getBinaryPkgAsync = binaryDir => {
const pathToPackageJson = getBinaryPkgPath(binaryDir);
debug('Reading binary package.json from:', pathToPackageJson);
return fs.pathExistsAsync(pathToPackageJson).then(exists => {
if (!exists) {
return null;
}
return fs.readJsonAsync(pathToPackageJson);
});
};
const getBinaryPkgVersion = o => _.get(o, 'version', null);
const getBinaryElectronVersion = o => _.get(o, 'electronVersion', null);
const getBinaryElectronNodeVersion = o => _.get(o, 'electronNodeVersion', null);
module.exports = {
getPathToExecutable,
getPlatformExecutable,
// those names start to sound like Java
getBinaryElectronNodeVersion,
getBinaryElectronVersion,
getBinaryPkgVersion,
getBinaryVerifiedAsync,
getBinaryPkgAsync,
getBinaryPkgPath,
getBinaryDir,
getCacheDir,
clearBinaryStateAsync,
writeBinaryVerifiedAsync,
parseRealPlatformBinaryFolderAsync,
getDistDir,
getVersionDir
};

201
CyLukTs/lukan/node_modules/cypress/lib/tasks/unzip.js generated vendored Normal file
View File

@ -0,0 +1,201 @@
"use strict";
const _ = require('lodash');
const la = require('lazy-ass');
const is = require('check-more-types');
const cp = require('child_process');
const os = require('os');
const yauzl = require('yauzl');
const debug = require('debug')('cypress:cli:unzip');
const extract = require('extract-zip');
const Promise = require('bluebird');
const readline = require('readline');
const {
throwFormErrorText,
errors
} = require('../errors');
const fs = require('../fs');
const util = require('../util');
const unzipTools = {
extract
};
// expose this function for simple testing
const unzip = ({
zipFilePath,
installDir,
progress
}) => {
debug('unzipping from %s', zipFilePath);
debug('into', installDir);
if (!zipFilePath) {
throw new Error('Missing zip filename');
}
const startTime = Date.now();
let yauzlDoneTime = 0;
return fs.ensureDirAsync(installDir).then(() => {
return new Promise((resolve, reject) => {
return yauzl.open(zipFilePath, (err, zipFile) => {
yauzlDoneTime = Date.now();
if (err) {
debug('error using yauzl %s', err.message);
return reject(err);
}
const total = zipFile.entryCount;
debug('zipFile entries count', total);
const started = new Date();
let percent = 0;
let count = 0;
const notify = percent => {
const elapsed = +new Date() - +started;
const eta = util.calculateEta(percent, elapsed);
progress.onProgress(percent, util.secsRemaining(eta));
};
const tick = () => {
count += 1;
percent = count / total * 100;
const displayPercent = percent.toFixed(0);
return notify(displayPercent);
};
const unzipWithNode = () => {
debug('unzipping with node.js (slow)');
const opts = {
dir: installDir,
onEntry: tick
};
debug('calling Node extract tool %s %o', zipFilePath, opts);
return unzipTools.extract(zipFilePath, opts).then(() => {
debug('node unzip finished');
return resolve();
}).catch(err => {
if (err) {
debug('error %s', err.message);
return reject(err);
}
});
};
const unzipFallback = _.once(unzipWithNode);
const unzipWithUnzipTool = () => {
debug('unzipping via `unzip`');
const inflatingRe = /inflating:/;
const sp = cp.spawn('unzip', ['-o', zipFilePath, '-d', installDir]);
sp.on('error', err => {
debug('unzip tool error: %s', err.message);
unzipFallback();
});
sp.on('close', code => {
debug('unzip tool close with code %d', code);
if (code === 0) {
percent = 100;
notify(percent);
return resolve();
}
debug('`unzip` failed %o', {
code
});
return unzipFallback();
});
sp.stdout.on('data', data => {
if (inflatingRe.test(data)) {
return tick();
}
});
sp.stderr.on('data', data => {
debug('`unzip` stderr %s', data);
});
};
// we attempt to first unzip with the native osx
// ditto because its less likely to have problems
// with corruption, symlinks, or icons causing failures
// and can handle resource forks
// http://automatica.com.au/2011/02/unzip-mac-os-x-zip-in-terminal/
const unzipWithOsx = () => {
debug('unzipping via `ditto`');
const copyingFileRe = /^copying file/;
const sp = cp.spawn('ditto', ['-xkV', zipFilePath, installDir]);
// f-it just unzip with node
sp.on('error', err => {
debug(err.message);
unzipFallback();
});
sp.on('close', code => {
if (code === 0) {
// make sure we get to 100% on the progress bar
// because reading in lines is not really accurate
percent = 100;
notify(percent);
return resolve();
}
debug('`ditto` failed %o', {
code
});
return unzipFallback();
});
return readline.createInterface({
input: sp.stderr
}).on('line', line => {
if (copyingFileRe.test(line)) {
return tick();
}
});
};
switch (os.platform()) {
case 'darwin':
return unzipWithOsx();
case 'linux':
return unzipWithUnzipTool();
case 'win32':
return unzipWithNode();
default:
return;
}
});
}).tap(() => {
debug('unzip completed %o', {
yauzlMs: yauzlDoneTime - startTime,
unzipMs: Date.now() - yauzlDoneTime
});
});
});
};
function isMaybeWindowsMaxPathLengthError(err) {
return os.platform() === 'win32' && err.code === 'ENOENT' && err.syscall === 'realpath';
}
const start = async ({
zipFilePath,
installDir,
progress
}) => {
la(is.unemptyString(installDir), 'missing installDir');
if (!progress) {
progress = {
onProgress: () => {
return {};
}
};
}
try {
const installDirExists = await fs.pathExists(installDir);
if (installDirExists) {
debug('removing existing unzipped binary', installDir);
await fs.removeAsync(installDir);
}
await unzip({
zipFilePath,
installDir,
progress
});
} catch (err) {
const errorTemplate = isMaybeWindowsMaxPathLengthError(err) ? errors.failedUnzipWindowsMaxPathLength : errors.failedUnzip;
await throwFormErrorText(errorTemplate)(err);
}
};
module.exports = {
start,
utils: {
unzip,
unzipTools
}
};

295
CyLukTs/lukan/node_modules/cypress/lib/tasks/verify.js generated vendored Normal file
View File

@ -0,0 +1,295 @@
"use strict";
const _ = require('lodash');
const chalk = require('chalk');
const {
Listr
} = require('listr2');
const debug = require('debug')('cypress:cli');
const {
stripIndent
} = require('common-tags');
const Promise = require('bluebird');
const logSymbols = require('log-symbols');
const path = require('path');
const os = require('os');
const verbose = require('../VerboseRenderer');
const {
throwFormErrorText,
errors
} = require('../errors');
const util = require('../util');
const logger = require('../logger');
const xvfb = require('../exec/xvfb');
const state = require('./state');
const VERIFY_TEST_RUNNER_TIMEOUT_MS = +util.getEnv('CYPRESS_VERIFY_TIMEOUT') || 30000;
const checkExecutable = binaryDir => {
const executable = state.getPathToExecutable(binaryDir);
debug('checking if executable exists', executable);
return util.isExecutableAsync(executable).then(isExecutable => {
debug('Binary is executable? :', isExecutable);
if (!isExecutable) {
return throwFormErrorText(errors.binaryNotExecutable(executable))();
}
}).catch({
code: 'ENOENT'
}, () => {
if (util.isCi()) {
return throwFormErrorText(errors.notInstalledCI(executable))();
}
return throwFormErrorText(errors.missingApp(binaryDir))(stripIndent`
Cypress executable not found at: ${chalk.cyan(executable)}
`);
});
};
const runSmokeTest = (binaryDir, options) => {
let executable = state.getPathToExecutable(binaryDir);
const onSmokeTestError = (smokeTestCommand, linuxWithDisplayEnv) => {
return err => {
debug('Smoke test failed:', err);
let errMessage = err.stderr || err.message;
debug('error message:', errMessage);
if (err.timedOut) {
debug('error timedOut is true');
return throwFormErrorText(errors.smokeTestFailure(smokeTestCommand, true))(errMessage);
}
if (linuxWithDisplayEnv && util.isBrokenGtkDisplay(errMessage)) {
util.logBrokenGtkDisplayWarning();
return throwFormErrorText(errors.invalidSmokeTestDisplayError)(errMessage);
}
return throwFormErrorText(errors.missingDependency)(errMessage);
};
};
const needsXvfb = xvfb.isNeeded();
debug('needs Xvfb?', needsXvfb);
/**
* Spawn Cypress running smoke test to check if all operating system
* dependencies are good.
*/
const spawn = linuxWithDisplayEnv => {
const random = _.random(0, 1000);
const args = ['--smoke-test', `--ping=${random}`];
if (needsSandbox()) {
// electron requires --no-sandbox to run as root
debug('disabling Electron sandbox');
args.unshift('--no-sandbox');
}
if (options.dev) {
executable = 'node';
args.unshift(path.resolve(__dirname, '..', '..', '..', 'scripts', 'start.js'));
}
const smokeTestCommand = `${executable} ${args.join(' ')}`;
debug('running smoke test');
debug('using Cypress executable %s', executable);
debug('smoke test command:', smokeTestCommand);
debug('smoke test timeout %d ms', options.smokeTestTimeout);
const env = _.extend({}, process.env, {
ELECTRON_ENABLE_LOGGING: true
});
const stdioOptions = _.extend({}, {
env,
timeout: options.smokeTestTimeout
});
return Promise.resolve(util.exec(executable, args, stdioOptions)).catch(onSmokeTestError(smokeTestCommand, linuxWithDisplayEnv)).then(result => {
// TODO: when execa > 1.1 is released
// change this to `result.all` for both stderr and stdout
// use lodash to be robust during tests against null result or missing stdout
const smokeTestStdout = _.get(result, 'stdout', '');
debug('smoke test stdout "%s"', smokeTestStdout);
if (!util.stdoutLineMatches(String(random), smokeTestStdout)) {
debug('Smoke test failed because could not find %d in:', random, result);
const smokeTestStderr = _.get(result, 'stderr', '');
const errorText = smokeTestStderr || smokeTestStdout;
return throwFormErrorText(errors.smokeTestFailure(smokeTestCommand, false))(errorText);
}
});
};
const spawnInXvfb = linuxWithDisplayEnv => {
return xvfb.start().then(() => {
return spawn(linuxWithDisplayEnv);
}).finally(xvfb.stop);
};
const userFriendlySpawn = linuxWithDisplayEnv => {
debug('spawning, should retry on display problem?', Boolean(linuxWithDisplayEnv));
return spawn(linuxWithDisplayEnv).catch({
code: 'INVALID_SMOKE_TEST_DISPLAY_ERROR'
}, () => {
return spawnInXvfb(linuxWithDisplayEnv);
});
};
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);
};
function testBinary(version, binaryDir, options) {
debug('running binary verification check', version);
// if running from 'cypress verify', don't print this message
if (!options.force) {
logger.log(stripIndent`
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
let renderer = util.isCi() ? verbose : 'default';
if (logger.logLevel() === 'silent') renderer = 'silent';
const rendererOptions = {
renderer
};
const tasks = new Listr([{
options: {
title: util.titleize('Verifying Cypress can run', chalk.gray(binaryDir))
},
task: (ctx, task) => {
debug('clearing out the verified version');
return state.clearBinaryStateAsync(binaryDir).then(() => {
return Promise.all([runSmokeTest(binaryDir, options), Promise.resolve().delay(1500) // good user experience
]);
}).then(() => {
debug('write verified: true');
return state.writeBinaryVerifiedAsync(true, binaryDir);
}).then(() => {
util.setTaskTitle(task, util.titleize(chalk.green('Verified Cypress!'), chalk.gray(binaryDir)), rendererOptions.renderer);
});
}
}], {
rendererOptions
});
return tasks.run();
}
const maybeVerify = (installedVersion, binaryDir, options) => {
return state.getBinaryVerifiedAsync(binaryDir).then(isVerified => {
debug('is Verified ?', isVerified);
let shouldVerify = !isVerified;
// force verify if options.force
if (options.force) {
debug('force verify');
shouldVerify = true;
}
if (shouldVerify) {
return testBinary(installedVersion, binaryDir, options).then(() => {
if (options.welcomeMessage) {
logger.log();
logger.log('Opening Cypress...');
}
});
}
});
};
const start = (options = {}) => {
debug('verifying Cypress app');
const packageVersion = util.pkgVersion();
let binaryDir = state.getBinaryDir(packageVersion);
_.defaults(options, {
dev: false,
force: false,
welcomeMessage: true,
smokeTestTimeout: VERIFY_TEST_RUNNER_TIMEOUT_MS
});
if (options.dev) {
return runSmokeTest('', options);
}
const parseBinaryEnvVar = () => {
const envBinaryPath = util.getEnv('CYPRESS_RUN_BINARY');
debug('CYPRESS_RUN_BINARY exists, =', envBinaryPath);
logger.log(stripIndent`
${chalk.yellow('Note:')} You have set the environment variable:
${chalk.white('CYPRESS_RUN_BINARY=')}${chalk.cyan(envBinaryPath)}
This overrides the default Cypress binary path used.
`);
logger.log();
return util.isExecutableAsync(envBinaryPath).then(isExecutable => {
debug('CYPRESS_RUN_BINARY is executable? :', isExecutable);
if (!isExecutable) {
return throwFormErrorText(errors.CYPRESS_RUN_BINARY.notValid(envBinaryPath))(stripIndent`
The supplied binary path is not executable
`);
}
}).then(() => {
return state.parseRealPlatformBinaryFolderAsync(envBinaryPath);
}).then(envBinaryDir => {
if (!envBinaryDir) {
return throwFormErrorText(errors.CYPRESS_RUN_BINARY.notValid(envBinaryPath))();
}
debug('CYPRESS_RUN_BINARY has binaryDir:', envBinaryDir);
binaryDir = envBinaryDir;
}).catch({
code: 'ENOENT'
}, err => {
return throwFormErrorText(errors.CYPRESS_RUN_BINARY.notValid(envBinaryPath))(err.message);
});
};
return Promise.try(() => {
debug('checking environment variables');
if (util.getEnv('CYPRESS_RUN_BINARY')) {
return parseBinaryEnvVar();
}
}).then(() => {
return checkExecutable(binaryDir);
}).tap(() => {
return debug('binaryDir is ', binaryDir);
}).then(() => {
return state.getBinaryPkgAsync(binaryDir);
}).then(pkg => {
return state.getBinaryPkgVersion(pkg);
}).then(binaryVersion => {
if (!binaryVersion) {
debug('no Cypress binary found for cli version ', packageVersion);
return throwFormErrorText(errors.missingApp(binaryDir))(`
Cannot read binary version from: ${chalk.cyan(state.getBinaryPkgPath(binaryDir))}
`);
}
debug(`Found binary version ${chalk.green(binaryVersion)} installed in: ${chalk.cyan(binaryDir)}`);
if (binaryVersion !== packageVersion) {
// warn if we installed with CYPRESS_INSTALL_BINARY or changed version
// in the package.json
logger.log(`Found binary version ${chalk.green(binaryVersion)} installed in: ${chalk.cyan(binaryDir)}`);
logger.log();
logger.warn(stripIndent`
${logSymbols.warning} Warning: Binary version ${chalk.green(binaryVersion)} does not match the expected package version ${chalk.green(packageVersion)}
These versions may not work properly together.
`);
logger.log();
}
return maybeVerify(binaryVersion, binaryDir, options);
}).catch(err => {
if (err.known) {
throw err;
}
return throwFormErrorText(errors.unexpected)(err.stack);
});
};
const isLinuxLike = () => os.platform() !== 'win32';
/**
* Returns true if running on a system where Electron needs "--no-sandbox" flag.
* @see https://crbug.com/638180
*
* On Debian we had problems running in sandbox even for non-root users.
* @see https://github.com/cypress-io/cypress/issues/5434
* Seems there is a lot of discussion around this issue among Electron users
* @see https://github.com/electron/electron/issues/17972
*/
const needsSandbox = () => isLinuxLike();
module.exports = {
start,
VERIFY_TEST_RUNNER_TIMEOUT_MS,
needsSandbox
};

478
CyLukTs/lukan/node_modules/cypress/lib/util.js generated vendored Normal file
View File

@ -0,0 +1,478 @@
"use strict";
const _ = require('lodash');
const arch = require('arch');
const os = require('os');
const ospath = require('ospath');
const crypto = require('crypto');
const la = require('lazy-ass');
const is = require('check-more-types');
const tty = require('tty');
const path = require('path');
const isCi = require('is-ci');
const execa = require('execa');
const getos = require('getos');
const chalk = require('chalk');
const Promise = require('bluebird');
const cachedir = require('cachedir');
const logSymbols = require('log-symbols');
const executable = require('executable');
const {
stripIndent
} = require('common-tags');
const supportsColor = require('supports-color');
const isInstalledGlobally = require('is-installed-globally');
const logger = require('./logger');
const debug = require('debug')('cypress:cli');
const fs = require('./fs');
const semver = require('semver');
const pkg = require(path.join(__dirname, '..', 'package.json'));
const issuesUrl = 'https://github.com/cypress-io/cypress/issues';
const getosAsync = Promise.promisify(getos);
/**
* Returns SHA512 of a file
*
* Implementation lifted from https://github.com/sindresorhus/hasha
* but without bringing that dependency (since hasha is Node v8+)
*/
const getFileChecksum = filename => {
la(is.unemptyString(filename), 'expected filename', filename);
const hashStream = () => {
const s = crypto.createHash('sha512');
s.setEncoding('hex');
return s;
};
return new Promise((resolve, reject) => {
const stream = fs.createReadStream(filename);
stream.on('error', reject).pipe(hashStream()).on('error', reject).on('finish', function () {
resolve(this.read());
});
});
};
const getFileSize = filename => {
la(is.unemptyString(filename), 'expected filename', filename);
return fs.statAsync(filename).get('size');
};
const isBrokenGtkDisplayRe = /Gtk: cannot open display/;
const stringify = val => {
return _.isObject(val) ? JSON.stringify(val) : val;
};
function normalizeModuleOptions(options = {}) {
return _.mapValues(options, stringify);
}
/**
* Returns true if the platform is Linux. We do a lot of different
* stuff on Linux (like Xvfb) and it helps to has readable code
*/
const isLinux = () => {
return os.platform() === 'linux';
};
/**
* If the DISPLAY variable is set incorrectly, when trying to spawn
* Cypress executable we get an error like this:
```
[1005:0509/184205.663837:WARNING:browser_main_loop.cc(258)] Gtk: cannot open display: 99
```
*/
const isBrokenGtkDisplay = str => {
return isBrokenGtkDisplayRe.test(str);
};
const isPossibleLinuxWithIncorrectDisplay = () => {
return isLinux() && process.env.DISPLAY;
};
const logBrokenGtkDisplayWarning = () => {
debug('Cypress exited due to a broken gtk display because of a potential invalid DISPLAY env... retrying after starting Xvfb');
// if we get this error, we are on Linux and DISPLAY is set
logger.warn(stripIndent`
${logSymbols.warning} Warning: Cypress failed to start.
This is likely due to a misconfigured DISPLAY environment variable.
DISPLAY was set to: "${process.env.DISPLAY}"
Cypress will attempt to fix the problem and rerun.
`);
logger.warn();
};
function stdoutLineMatches(expectedLine, stdout) {
const lines = stdout.split('\n').map(val => val.trim());
return lines.some(line => line === expectedLine);
}
/**
* Confirms if given value is a valid CYPRESS_INTERNAL_ENV value. Undefined values
* are valid, because the system can set the default one.
*
* @param {string} value
* @example util.isValidCypressInternalEnvValue(process.env.CYPRESS_INTERNAL_ENV)
*/
function isValidCypressInternalEnvValue(value) {
if (_.isUndefined(value)) {
// will get default value
return true;
}
// names of config environments, see "packages/server/config/app.json"
const names = ['development', 'test', 'staging', 'production'];
return _.includes(names, value);
}
/**
* Confirms if given value is a non-production CYPRESS_INTERNAL_ENV value.
* Undefined values are valid, because the system can set the default one.
*
* @param {string} value
* @example util.isNonProductionCypressInternalEnvValue(process.env.CYPRESS_INTERNAL_ENV)
*/
function isNonProductionCypressInternalEnvValue(value) {
return !_.isUndefined(value) && value !== 'production';
}
/**
* Prints NODE_OPTIONS using debug() module, but only
* if DEBUG=cypress... is set
*/
function printNodeOptions(log = debug) {
if (!log.enabled) {
return;
}
if (process.env.NODE_OPTIONS) {
log('NODE_OPTIONS=%s', process.env.NODE_OPTIONS);
} else {
log('NODE_OPTIONS is not set');
}
}
/**
* Removes double quote characters
* from the start and end of the given string IF they are both present
*
* @param {string} str Input string
* @returns {string} Trimmed string or the original string if there are no double quotes around it.
* @example
```
dequote('"foo"')
// returns string 'foo'
dequote('foo')
// returns string 'foo'
```
*/
const dequote = str => {
la(is.string(str), 'expected a string to remove double quotes', str);
if (str.length > 1 && str[0] === '"' && str[str.length - 1] === '"') {
return str.substr(1, str.length - 2);
}
return str;
};
const parseOpts = opts => {
opts = _.pick(opts, 'autoCancelAfterFailures', 'browser', 'cachePath', 'cacheList', 'cacheClear', 'cachePrune', 'ciBuildId', 'ct', 'component', 'config', 'configFile', 'cypressVersion', 'destination', 'detached', 'dev', 'e2e', 'exit', 'env', 'force', 'global', 'group', 'headed', 'headless', 'inspect', 'inspectBrk', 'key', 'path', 'parallel', 'port', 'project', 'quiet', 'reporter', 'reporterOptions', 'record', 'runProject', 'spec', 'tag');
if (opts.exit) {
opts = _.omit(opts, 'exit');
}
// some options might be quoted - which leads to unexpected results
// remove double quotes from certain options
const cleanOpts = {
...opts
};
const toDequote = ['group', 'ciBuildId'];
for (const prop of toDequote) {
if (_.has(opts, prop)) {
cleanOpts[prop] = dequote(opts[prop]);
}
}
debug('parsed cli options %o', cleanOpts);
return cleanOpts;
};
/**
* Copy of packages/server/lib/browsers/utils.ts
* because we need same functionality in CLI to show the path :(
*/
const getApplicationDataFolder = (...paths) => {
const {
env
} = process;
// allow overriding the app_data folder
let folder = env.CYPRESS_CONFIG_ENV || env.CYPRESS_INTERNAL_ENV || 'development';
const PRODUCT_NAME = pkg.productName || pkg.name;
const OS_DATA_PATH = ospath.data();
const ELECTRON_APP_DATA_PATH = path.join(OS_DATA_PATH, PRODUCT_NAME);
if (process.env.CYPRESS_INTERNAL_E2E_TESTING_SELF) {
folder = `${folder}-e2e-test`;
}
const p = path.join(ELECTRON_APP_DATA_PATH, 'cy', folder, ...paths);
return p;
};
const util = {
normalizeModuleOptions,
parseOpts,
isValidCypressInternalEnvValue,
isNonProductionCypressInternalEnvValue,
printNodeOptions,
isCi() {
return isCi;
},
getEnvOverrides(options = {}) {
return _.chain({}).extend(util.getEnvColors()).extend(util.getForceTty()).omitBy(_.isUndefined) // remove undefined values
.mapValues(value => {
// stringify to 1 or 0
return value ? '1' : '0';
}).extend(util.getOriginalNodeOptions()).value();
},
getOriginalNodeOptions() {
const opts = {};
if (process.env.NODE_OPTIONS) {
opts.ORIGINAL_NODE_OPTIONS = process.env.NODE_OPTIONS;
}
// https://github.com/cypress-io/cypress/issues/18914
// Node 17+ ships with OpenSSL 3 by default, so we may need the option
// --openssl-legacy-provider so that webpack@4 can use the legacy MD4 hash
// function. This option doesn't exist on Node <17 or when it is built
// against OpenSSL 1, so we have to detect Node's major version and check
// which version of OpenSSL it was built against before spawning the plugins
// process.
// To be removed when the Cypress binary pulls in the @cypress/webpack-batteries-included-preprocessor
// version that has been updated to webpack >= 5.61, which no longer relies on
// Node's builtin crypto.hash function.
if (process.versions && semver.satisfies(process.versions.node, '>=17.0.0') && semver.satisfies(process.versions.openssl, '>=3', {
includePrerelease: true
})) {
opts.ORIGINAL_NODE_OPTIONS = `${opts.ORIGINAL_NODE_OPTIONS || ''} --openssl-legacy-provider`;
}
return opts;
},
getForceTty() {
return {
FORCE_STDIN_TTY: util.isTty(process.stdin.fd),
FORCE_STDOUT_TTY: util.isTty(process.stdout.fd),
FORCE_STDERR_TTY: util.isTty(process.stderr.fd)
};
},
getEnvColors() {
const sc = util.supportsColor();
return {
FORCE_COLOR: sc,
DEBUG_COLORS: sc,
MOCHA_COLORS: sc ? true : undefined
};
},
isTty(fd) {
return tty.isatty(fd);
},
supportsColor() {
// if we've been explictly told not to support
// color then turn this off
if (process.env.NO_COLOR) {
return false;
}
// https://github.com/cypress-io/cypress/issues/1747
// always return true in CI providers
if (process.env.CI) {
return true;
}
// ensure that both stdout and stderr support color
return Boolean(supportsColor.stdout) && Boolean(supportsColor.stderr);
},
cwd() {
return process.cwd();
},
pkgBuildInfo() {
return pkg.buildInfo;
},
pkgVersion() {
return pkg.version;
},
exit(code) {
process.exit(code);
},
logErrorExit1(err) {
logger.error(err.message);
process.exit(1);
},
dequote,
titleize(...args) {
// prepend first arg with space
// and pad so that all messages line up
args[0] = _.padEnd(` ${args[0]}`, 24);
// get rid of any falsy values
args = _.compact(args);
return chalk.blue(...args);
},
calculateEta(percent, elapsed) {
// returns the number of seconds remaining
// if we're at 100% already just return 0
if (percent === 100) {
return 0;
}
// take the percentage and divide by one
// and multiple that against elapsed
// subtracting what's already elapsed
return elapsed * (1 / (percent / 100)) - elapsed;
},
convertPercentToPercentage(num) {
// convert a percent with values between 0 and 1
// with decimals, so that it is between 0 and 100
// and has no decimal places
return Math.round(_.isFinite(num) ? num * 100 : 0);
},
secsRemaining(eta) {
// calculate the seconds reminaing with no decimal places
return (_.isFinite(eta) ? eta / 1000 : 0).toFixed(0);
},
setTaskTitle(task, title, renderer) {
// only update the renderer title when not running in CI
if (renderer === 'default' && task.title !== title) {
task.title = title;
}
},
isInstalledGlobally() {
return isInstalledGlobally;
},
isSemver(str) {
return /^(\d+\.)?(\d+\.)?(\*|\d+)$/.test(str);
},
isExecutableAsync(filePath) {
return Promise.resolve(executable(filePath));
},
isLinux,
getOsVersionAsync() {
return Promise.try(() => {
if (isLinux()) {
return getosAsync().then(osInfo => {
return [osInfo.dist, osInfo.release].join(' - ');
}).catch(() => {
return os.release();
});
}
return os.release();
});
},
async getPlatformInfo() {
const [version, osArch] = await Promise.all([util.getOsVersionAsync(), this.getRealArch()]);
return stripIndent`
Platform: ${os.platform()}-${osArch} (${version})
Cypress Version: ${util.pkgVersion()}
`;
},
_cachedArch: undefined,
/**
* Attempt to return the real system arch (not process.arch, which is only the Node binary's arch)
*/
async getRealArch() {
if (this._cachedArch) return this._cachedArch;
async function _getRealArch() {
const osPlatform = os.platform();
// eslint-disable-next-line no-restricted-syntax
const osArch = os.arch();
debug('detecting arch %o', {
osPlatform,
osArch
});
if (osArch === 'arm64') return 'arm64';
if (osPlatform === 'darwin') {
// could possibly be x64 node on arm64 darwin, check if we are being translated by Rosetta
// https://stackoverflow.com/a/65347893/3474615
const {
stdout
} = await execa('sysctl', ['-n', 'sysctl.proc_translated']).catch(() => '');
debug('rosetta check result: %o', {
stdout
});
if (stdout === '1') return 'arm64';
}
if (osPlatform === 'linux') {
// could possibly be x64 node on arm64 linux, check the "machine hardware name"
// list of names for reference: https://stackoverflow.com/a/45125525/3474615
const {
stdout
} = await execa('uname', ['-m']).catch(() => '');
debug('arm uname -m result: %o ', {
stdout
});
if (['aarch64_be', 'aarch64', 'armv8b', 'armv8l'].includes(stdout)) return 'arm64';
}
// eslint-disable-next-line no-restricted-syntax
const pkgArch = arch();
if (pkgArch === 'x86') return 'ia32';
return pkgArch;
}
return this._cachedArch = await _getRealArch();
},
// attention:
// when passing relative path to NPM post install hook, the current working
// directory is set to the `node_modules/cypress` folder
// the user is probably passing relative path with respect to root package folder
formAbsolutePath(filename) {
if (path.isAbsolute(filename)) {
return filename;
}
return path.join(process.cwd(), '..', '..', filename);
},
getEnv(varName, trim) {
la(is.unemptyString(varName), 'expected environment variable name, not', varName);
const configVarName = `npm_config_${varName}`;
const configVarNameLower = configVarName.toLowerCase();
const packageConfigVarName = `npm_package_config_${varName}`;
let result;
if (process.env.hasOwnProperty(varName)) {
debug(`Using ${varName} from environment variable`);
result = process.env[varName];
} else if (process.env.hasOwnProperty(configVarName)) {
debug(`Using ${varName} from npm config`);
result = process.env[configVarName];
} else if (process.env.hasOwnProperty(configVarNameLower)) {
debug(`Using ${varName.toLowerCase()} from npm config`);
result = process.env[configVarNameLower];
} else if (process.env.hasOwnProperty(packageConfigVarName)) {
debug(`Using ${varName} from package.json config`);
result = process.env[packageConfigVarName];
}
// environment variables are often set double quotes to escape characters
// and on Windows it can lead to weird things: for example
// set FOO="C:\foo.txt" && node -e "console.log('>>>%s<<<', process.env.FOO)"
// will print
// >>>"C:\foo.txt" <<<
// see https://github.com/cypress-io/cypress/issues/4506#issuecomment-506029942
// so for sanity sake we should first trim whitespace characters and remove
// double quotes around environment strings if the caller is expected to
// use this environment string as a file path
return trim ? dequote(_.trim(result)) : result;
},
getCacheDir() {
return cachedir('Cypress');
},
isPostInstall() {
return process.env.npm_lifecycle_event === 'postinstall';
},
exec: execa,
stdoutLineMatches,
issuesUrl,
isBrokenGtkDisplay,
logBrokenGtkDisplayWarning,
isPossibleLinuxWithIncorrectDisplay,
getGitHubIssueUrl(number) {
la(is.positive(number), 'github issue should be a positive number', number);
la(_.isInteger(number), 'github issue should be an integer', number);
return `${issuesUrl}/${number}`;
},
getFileChecksum,
getFileSize,
getApplicationDataFolder
};
module.exports = util;