#!/usr/bin/env node require('../lib/node-version-check'); // @note that this should not respect CLI --silent const _ = require('lodash'), waterfall = require('async/waterfall'), { Command } = require('commander'), program = new Command(), version = require('../package.json').version, newman = require('../'), util = require('./util'); program .name('newman') .addHelpCommand(false) .version(version, '-v, --version'); // The `run` command allows you to specify a collection to be run with the provided options. program .command('run ') .description('Initiate a Postman Collection run from a given URL or path') .usage(' [options]') .option('-e, --environment ', 'Specify a URL or path to a Postman Environment') .option('-g, --globals ', 'Specify a URL or path to a file containing Postman Globals') .option('-r, --reporters [reporters]', 'Specify the reporters to use for this run', util.cast.csvParse, ['cli']) .option('-n, --iteration-count ', 'Define the number of iterations to run', util.cast.integer) .option('-d, --iteration-data ', 'Specify a data file to use for iterations (either JSON or CSV)') .option('--folder ', 'Specify the folder to run from a collection. Can be specified multiple times to run multiple folders', util.cast.memoize, []) .option('--global-var ', 'Allows the specification of global variables via the command line, in a key=value format', util.cast.memoizeKeyVal, []) .option('--env-var ', 'Allows the specification of environment variables via the command line, in a key=value format', util.cast.memoizeKeyVal, []) .option('--export-environment ', 'Exports the final environment to a file after completing the run') .option('--export-globals ', 'Exports the final globals to a file after completing the run') .option('--export-collection ', 'Exports the executed collection to a file after completing the run') .option('--postman-api-key ', 'API Key used to load the resources from the Postman API') .option('--bail [modifiers]', 'Specify whether or not to gracefully stop a collection run on encountering an error' + ' and whether to end the run with an error based on the optional modifier', util.cast.csvParse) .option('--ignore-redirects', 'Prevents Newman from automatically following 3XX redirect responses') .option('-x , --suppress-exit-code', 'Specify whether or not to override the default exit code for the current run') .option('--silent', 'Prevents Newman from showing output to CLI') .option('--disable-unicode', 'Forces Unicode compliant symbols to be replaced by their plain text equivalents') .option('--color ', 'Enable/Disable colored output (auto|on|off)', util.cast.colorOptions, 'auto') .option('--delay-request [n]', 'Specify the extent of delay between requests (milliseconds)', util.cast.integer, 0) .option('--timeout [n]', 'Specify a timeout for collection run (milliseconds)', util.cast.integer, 0) .option('--timeout-request [n]', 'Specify a timeout for requests (milliseconds)', util.cast.integer, 0) .option('--timeout-script [n]', 'Specify a timeout for scripts (milliseconds)', util.cast.integer, 0) .option('--working-dir ', 'Specify the path to the working directory') .option('--no-insecure-file-read', 'Prevents reading the files situated outside of the working directory') .option('-k, --insecure', 'Disables SSL validations') .option('--ssl-client-cert-list ', 'Specify the path to a client certificates configurations (JSON)') .option('--ssl-client-cert ', 'Specify the path to a client certificate (PEM)') .option('--ssl-client-key ', 'Specify the path to a client certificate private key') .option('--ssl-client-passphrase ', 'Specify the client certificate passphrase (for protected key)') .option('--ssl-extra-ca-certs ', 'Specify additionally trusted CA certificates (PEM)') .option('--cookie-jar ', 'Specify the path to a custom cookie jar (serialized tough-cookie JSON) ') .option('--export-cookie-jar ', 'Exports the cookie jar to a file after completing the run') .option('--verbose', 'Show detailed information of collection run and each request sent') .action((collection, command) => { let options = util.commanderToObject(command), // parse custom reporter options reporterOptions = util.parseNestedOptions(program._originalArgs, '--reporter-', options.reporters); // Inject additional properties into the options object options.collection = collection; options.reporterOptions = reporterOptions._generic; options.reporter = _.transform(_.omit(reporterOptions, '_generic'), (acc, value, key) => { acc[key] = _.assignIn(value, reporterOptions._generic); // overrides reporter options with _generic }, {}); newman.run(options, function (err, summary) { const runError = err || summary.run.error || summary.run.failures.length; if (err) { console.error(`error: ${err.message || err}\n`); err.friendly && console.error(` ${err.friendly}\n`); } runError && !_.get(options, 'suppressExitCode') && process.exit(1); }); }); program.addHelpText('after', ` To get available options for a command: newman -h`); // Warn on invalid command and then exits. program.on('command:*', (command) => { console.error(`error: invalid command \`${command}\`\n`); program.help(); }); /** * Starts the script execution. * callback is required when this is required as a module in tests. * * @param {String[]} argv - Argument vector. * @param {?Function} callback - The callback function invoked on the completion of execution. */ function run (argv, callback) { waterfall([ (next) => { // cache original argv, required to parse nested options later. program._originalArgs = argv; // omit custom nested options, otherwise commander will throw unknown options error next(null, util.omitNestedOptions(argv, '--reporter-')); }, (args, next) => { let error = null; try { program.parse(args); } catch (err) { error = err; } next(error); }, (next) => { // throw error if no argument is provided. next(program.args.length ? null : new Error('no arguments provided')); } ], (error) => { // invoke callback if this is required as module, used in tests. if (callback) { return callback(error); } // in case of an error, log error message and print help message. if (error) { console.error(`error: ${error.message || error}\n`); program.help(); } }); } // This hack has been added from https://github.com/nodejs/node/issues/6456#issue-151760275 // @todo: remove when https://github.com/nodejs/node/issues/6456 has been fixed (Number(process.version[1]) >= 6) && [process.stdout, process.stderr].forEach((s) => { s && s.isTTY && s._handle && s._handle.setBlocking && s._handle.setBlocking(true); }); // Run this script if this is a direct stdin. !module.parent && run(process.argv); // Export to allow debugging and testing. module.exports = run;