mirror of
https://github.com/cypress-io/cypress.git
synced 2026-05-03 05:20:38 -05:00
Support --tag argument (#5164)
* Alphabetize cli options for my own sanity * begin added tag flag * Fix some minor grammar in cli help output + be more specific for specs description * update snapshot based on alphabetization change * update snapshot to include --tag in help output * update logic for pulling out space delimited args to look through --tag and --spec flags dynamically * Support and pass along tag flag to run and record - show err if passed without record flag - sanitize args into comma separated string - display tag in record errors * fix some tests/snapshots where 'tag' was missing * Actually try passing in tag through tests to ensure it prints. * Merge branch 'develop' into issue-2561-tags # Conflicts: # cli/__snapshots__/cli_spec.js # cli/lib/cli.js # cli/lib/exec/run.js # packages/server/lib/modes/run.js # packages/server/lib/util/args.js * Send 'tags' as an array to backend API * Update json-schemas to query against 2.2.0 of postRun - this will require a bump to json-schemas repo * update test to reflect tags array * update snapshot to display nightly tag * rearrange args to alphabetical order in specs * Add tags to runResponses / remove tag from incorrect instance post * Fix failing specs / snapshots * Update error messages + snapshots * Fix snapshot that no longer displays tag arg * fix args unit test * remove extra slash * add a few more cli tests * another test just in case * a quick unit test for displayFlags utility Co-authored-by: Gleb Bahmutov <gleb.bahmutov@gmail.com>
This commit is contained in:
+89
-83
@@ -25,99 +25,107 @@ const coerceFalse = (arg) => {
|
||||
return arg !== 'false'
|
||||
}
|
||||
|
||||
const spaceDelimitedSpecsMsg = (files) => {
|
||||
logger.log()
|
||||
logger.warn(stripIndent`
|
||||
${
|
||||
logSymbols.warning
|
||||
} Warning: It looks like you're passing --spec a space-separated list of files:
|
||||
const spaceDelimitedArgsMsg = (flag, args) => {
|
||||
let msg = `
|
||||
${logSymbols.warning} Warning: It looks like you're passing --${flag} a space-separated list of arguments:
|
||||
|
||||
"${files.join(' ')}"
|
||||
"${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"
|
||||
`
|
||||
}
|
||||
|
||||
If you are trying to pass multiple spec filenames, separate them by commas instead:
|
||||
cypress run --spec spec1,spec2,spec3
|
||||
`)
|
||||
|
||||
logger.log()
|
||||
logger.warn(stripIndent(msg))
|
||||
logger.log()
|
||||
}
|
||||
|
||||
const parseVariableOpts = (fnArgs, args) => {
|
||||
const opts = fnArgs.pop()
|
||||
|
||||
if (fnArgs.length && opts.spec) {
|
||||
// this will capture space-delimited specs after --spec spec1 but before the next option
|
||||
if (fnArgs.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 argIndex = _.indexOf(args, '--spec') + 2
|
||||
const nextOptOffset = _.findIndex(_.slice(args, argIndex), (arg) => {
|
||||
return _.startsWith(arg, '--')
|
||||
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, fnArgs)
|
||||
|
||||
if (extraArgs.length) {
|
||||
opts[flag] = [opts[flag]].concat(extraArgs)
|
||||
spaceDelimitedArgsMsg(flag, opts[flag])
|
||||
opts[flag] = opts[flag].join(',')
|
||||
}
|
||||
})
|
||||
const endIndex =
|
||||
nextOptOffset !== -1 ? argIndex + nextOptOffset : args.length
|
||||
|
||||
const maybeSpecs = _.slice(args, argIndex, endIndex)
|
||||
const extraSpecs = _.intersection(maybeSpecs, fnArgs)
|
||||
|
||||
if (extraSpecs.length) {
|
||||
opts.spec = [opts.spec].concat(extraSpecs)
|
||||
spaceDelimitedSpecsMsg(opts.spec)
|
||||
opts.spec = opts.spec.join(',')
|
||||
}
|
||||
}
|
||||
|
||||
return util.parseOpts(opts)
|
||||
}
|
||||
|
||||
const descriptions = {
|
||||
record:
|
||||
'records the run. sends test results, screenshots and videos to your Cypress Dashboard.',
|
||||
key:
|
||||
'your secret Record Key. you can omit this if you set a CYPRESS_RECORD_KEY environment variable.',
|
||||
spec: 'runs a specific spec file. defaults to "all"',
|
||||
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"',
|
||||
port: 'runs Cypress on a specific port. overrides any value in the configuration file.',
|
||||
env: 'sets environment variables. separate multiple values with a comma. overrides any value in the configuration file or cypress.env.json',
|
||||
config: 'sets configuration values. separate multiple values with a comma. overrides any value in the configuration file.',
|
||||
browserRunMode: '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.',
|
||||
browserOpenMode: 'path to a custom browser to be added to the list of available browsers in Cypress',
|
||||
detached: 'runs Cypress application in detached mode',
|
||||
project: 'path to the project',
|
||||
global: 'force Cypress into global mode as if its globally installed',
|
||||
configFile: 'path to JSON file where configuration values are set. defaults to "cypress.json". pass "false" to disable.',
|
||||
version: 'prints Cypress version',
|
||||
headed: 'displays the Electron browser instead of running headlessly',
|
||||
dev: 'runs cypress in development and bypasses binary check',
|
||||
forceInstall: 'force install the Cypress binary',
|
||||
exit: 'keep the browser open after tests finish',
|
||||
cachePath: 'print the path to the binary cache',
|
||||
cacheList: 'list cached binary versions',
|
||||
browserRunMode: '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',
|
||||
group: 'a named group for recorded runs in the Cypress dashboard',
|
||||
parallel:
|
||||
'enables concurrent runs and automatic load balancing of specs across multiple machines or processes',
|
||||
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',
|
||||
cacheList: 'list cached binary versions',
|
||||
cachePath: 'print the path to the binary cache',
|
||||
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',
|
||||
config: 'sets configuration values. separate multiple values with a comma. overrides any value in cypress.json.',
|
||||
configFile: 'path to JSON file where configuration values are set. defaults to "cypress.json". pass "false" to disable.',
|
||||
detached: 'runs Cypress application in detached mode',
|
||||
dev: 'runs cypress in development and bypasses binary check',
|
||||
env: 'sets environment variables. separate multiple values with a comma. overrides any value in cypress.json 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 the Cypress Dashboard',
|
||||
headed: 'displays the Electron browser instead of running headlessly',
|
||||
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.json.',
|
||||
project: 'path to the project',
|
||||
record: 'records the run. sends test results, screenshots and videos to your Cypress Dashboard.',
|
||||
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 the Cypress Dashboard',
|
||||
version: 'prints Cypress version',
|
||||
}
|
||||
|
||||
const knownCommands = [
|
||||
'version',
|
||||
'run',
|
||||
'open',
|
||||
'install',
|
||||
'verify',
|
||||
'-v',
|
||||
'--version',
|
||||
'cache',
|
||||
'help',
|
||||
'-h',
|
||||
'--help',
|
||||
'cache',
|
||||
'install',
|
||||
'open',
|
||||
'run',
|
||||
'verify',
|
||||
'-v',
|
||||
'--version',
|
||||
'version',
|
||||
]
|
||||
|
||||
const text = (description) => {
|
||||
@@ -165,7 +173,7 @@ module.exports = {
|
||||
|
||||
const program = new commander.Command()
|
||||
|
||||
// bug in commaner not printing name
|
||||
// bug in commander not printing name
|
||||
// in usage help docs
|
||||
program._name = 'cypress'
|
||||
|
||||
@@ -188,25 +196,23 @@ module.exports = {
|
||||
.command('run')
|
||||
.usage('[options]')
|
||||
.description('Runs Cypress tests from the CLI without the GUI')
|
||||
.option('--record [bool]', text('record'), coerceFalse)
|
||||
.option('--headed', text('headed'))
|
||||
.option('-k, --key <record-key>', text('key'))
|
||||
.option('-s, --spec <spec>', text('spec'))
|
||||
.option('-r, --reporter <reporter>', text('reporter'))
|
||||
.option(
|
||||
'-o, --reporter-options <reporter-options>',
|
||||
text('reporterOptions')
|
||||
)
|
||||
.option('-p, --port <port>', text('port'))
|
||||
.option('-e, --env <env>', text('env'))
|
||||
.option('-b, --browser <browser-name-or-path>', text('browserRunMode'))
|
||||
.option('--ci-build-id <id>', text('ciBuildId'))
|
||||
.option('-c, --config <config>', text('config'))
|
||||
.option('-C, --config-file <config-file>', text('configFile'))
|
||||
.option('-b, --browser <browser-name-or-path>', text('browserRunMode'))
|
||||
.option('-P, --project <project-path>', text('project'))
|
||||
.option('--parallel', text('parallel'))
|
||||
.option('-e, --env <env>', text('env'))
|
||||
.option('--group <name>', text('group'))
|
||||
.option('--ci-build-id <id>', text('ciBuildId'))
|
||||
.option('-k, --key <record-key>', text('key'))
|
||||
.option('--headed', text('headed'))
|
||||
.option('--no-exit', text('exit'))
|
||||
.option('--parallel', text('parallel'))
|
||||
.option('-p, --port <port>', text('port'))
|
||||
.option('-P, --project <project-path>', text('project'))
|
||||
.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((...fnArgs) => {
|
||||
debug('running Cypress')
|
||||
@@ -220,14 +226,14 @@ module.exports = {
|
||||
.command('open')
|
||||
.usage('[options]')
|
||||
.description('Opens Cypress in the interactive GUI.')
|
||||
.option('-p, --port <port>', text('port'))
|
||||
.option('-e, --env <env>', text('env'))
|
||||
.option('-b, --browser <browser-path>', text('browserOpenMode'))
|
||||
.option('-c, --config <config>', text('config'))
|
||||
.option('-C, --config-file <config-file>', text('configFile'))
|
||||
.option('-d, --detached [bool]', text('detached'), coerceFalse)
|
||||
.option('-b, --browser <browser-path>', text('browserOpenMode'))
|
||||
.option('-P, --project <project-path>', text('project'))
|
||||
.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')
|
||||
|
||||
Reference in New Issue
Block a user