diff --git a/bin/commands/runs.js b/bin/commands/runs.js index e08154d0..613a92e4 100644 --- a/bin/commands/runs.js +++ b/bin/commands/runs.js @@ -46,7 +46,7 @@ module.exports = function run(args) { utils.setParallels(bsConfig, args); // Archive the spec files - return archiver.archive(bsConfig.run_settings, config.fileName).then(function (data) { + return archiver.archive(bsConfig.run_settings, config.fileName, args.exclude).then(function (data) { // Uploaded zip file return zipUploader.zipUpload(bsConfig, config.fileName).then(function (zip) { @@ -56,7 +56,7 @@ module.exports = function run(args) { let message = `${data.message}! ${Constants.userMessages.BUILD_CREATED} with build id: ${data.build_id}`; let dashboardLink = `${Constants.userMessages.VISIT_DASHBOARD} ${config.dashboardUrl}${data.build_id}`; utils.exportResults(data.build_id, `${config.dashboardUrl}${data.build_id}`); - if ((utils.isUndefined(bsConfig.run_settings.parallels) && utils.isUndefined(args.parallels)) || (!utils.isUndefined(bsConfig.run_settings.parallels) && bsConfig.run_settings.parallels == Constants.constants.DEFAULT_PARALLEL_MESSAGE)) { + if ((utils.isUndefined(bsConfig.run_settings.parallels) && utils.isUndefined(args.parallels)) || (!utils.isUndefined(bsConfig.run_settings.parallels) && bsConfig.run_settings.parallels == Constants.cliMessages.RUN.DEFAULT_PARALLEL_MESSAGE)) { logger.warn(Constants.userMessages.NO_PARALLELS); } diff --git a/bin/helpers/archiver.js b/bin/helpers/archiver.js index 24e9c854..d4b5ab44 100644 --- a/bin/helpers/archiver.js +++ b/bin/helpers/archiver.js @@ -2,9 +2,11 @@ const fs = require("fs"); const archiver = require("archiver"), - logger = require("./logger").winstonLogger; + Constants = require('../helpers/constants'), + logger = require("./logger").winstonLogger, + utils = require('../helpers/utils'); -const archiveSpecs = (runSettings, filePath) => { +const archiveSpecs = (runSettings, filePath, excludeFiles) => { return new Promise(function (resolve, reject) { var output = fs.createWriteStream(filePath); @@ -36,9 +38,10 @@ const archiveSpecs = (runSettings, filePath) => { archive.pipe(output); - let allowedFileTypes = [ 'js', 'json', 'txt', 'ts', 'feature', 'features', 'pdf', 'jpg', 'jpeg', 'png', 'zip' ]; - allowedFileTypes.forEach(fileType => { - archive.glob(`**/*.${fileType}`, { cwd: cypressFolderPath, matchBase: true, ignore: ['**/node_modules/**', './node_modules/**', 'package-lock.json', 'package.json', 'browserstack-package.json', 'tests.zip'] }); + let ignoreFiles = getFilesToIgnore(runSettings, excludeFiles); + + Constants.allowedFileTypes.forEach(fileType => { + archive.glob(`**/*.${fileType}`, { cwd: cypressFolderPath, matchBase: true, ignore: ignoreFiles }); }); let packageJSON = {}; @@ -60,4 +63,21 @@ const archiveSpecs = (runSettings, filePath) => { }); } +const getFilesToIgnore = (runSettings, excludeFiles) => { + let ignoreFiles = Constants.filesToIgnoreWhileUploading; + + // exclude files asked by the user + // args will take precedence over config file + if (!utils.isUndefined(excludeFiles)) { + let excludePatterns = utils.fixCommaSeparatedString(excludeFiles).split(','); + ignoreFiles = ignoreFiles.concat(excludePatterns); + logger.info(`Excluding files matching: ${JSON.stringify(excludePatterns)}`); + } else if (!utils.isUndefined(runSettings.exclude) && runSettings.exclude.length) { + ignoreFiles = ignoreFiles.concat(runSettings.exclude); + logger.info(`Excluding files matching: ${JSON.stringify(runSettings.exclude)}`); + } + + return ignoreFiles; +} + exports.archive = archiveSpecs diff --git a/bin/helpers/capabilityHelper.js b/bin/helpers/capabilityHelper.js index d24cdc8d..04fea139 100644 --- a/bin/helpers/capabilityHelper.js +++ b/bin/helpers/capabilityHelper.js @@ -77,7 +77,7 @@ const caps = (bsConfig, zip) => { } } - if(obj.parallels === Constants.constants.DEFAULT_PARALLEL_MESSAGE) obj.parallels = undefined + if(obj.parallels === Constants.cliMessages.RUN.DEFAULT_PARALLEL_MESSAGE) obj.parallels = undefined if (obj.project) logger.log(`Project name is: ${obj.project}`); diff --git a/bin/helpers/constants.js b/bin/helpers/constants.js index 92ecd1b2..945eb3c5 100644 --- a/bin/helpers/constants.js +++ b/bin/helpers/constants.js @@ -61,6 +61,8 @@ const cliMessages = { DESC: "Path to BrowserStack config", CONFIG_DEMAND: "config file is required", BUILD_NAME: "The build name you want to use to name your test runs", + EXCLUDE: "Exclude files matching a pattern from zipping and uploading", + DEFAULT_PARALLEL_MESSAGE: "Here goes the number of parallels you want to run", SPECS_DESCRIPTION: 'Specify the spec files to run', ENV_DESCRIPTION: "Specify the environment variables for your spec files" }, @@ -81,14 +83,15 @@ const messageTypes = { NULL: null } -const constants = { - DEFAULT_PARALLEL_MESSAGE: "Here goes the number of parallels you want to run" -} +const allowedFileTypes = ['js', 'json', 'txt', 'ts', 'feature', 'features', 'pdf', 'jpg', 'jpeg', 'png', 'zip']; + +const filesToIgnoreWhileUploading = ['node_modules/**', 'package-lock.json', 'package.json', 'browserstack-package.json', 'tests.zip'] module.exports = Object.freeze({ userMessages, cliMessages, validationMessages, messageTypes, - constants + allowedFileTypes, + filesToIgnoreWhileUploading }); diff --git a/bin/helpers/utils.js b/bin/helpers/utils.js index 945df8fb..241937ac 100644 --- a/bin/helpers/utils.js +++ b/bin/helpers/utils.js @@ -152,7 +152,7 @@ exports.isUndefined = value => (value === undefined || value === null); exports.isFloat = value => (Number(value) && Number(value) % 1 !== 0); exports.isParallelValid = (value) => { - return this.isUndefined(value) || !(isNaN(value) || this.isFloat(value) || parseInt(value, 10) === 0 || parseInt(value, 10) < -1) || value === Constants.constants.DEFAULT_PARALLEL_MESSAGE; + return this.isUndefined(value) || !(isNaN(value) || this.isFloat(value) || parseInt(value, 10) === 0 || parseInt(value, 10) < -1) || value === Constants.cliMessages.RUN.DEFAULT_PARALLEL_MESSAGE; } exports.getUserAgent = () => { diff --git a/bin/runner.js b/bin/runner.js index 99f0bca6..edc4f9a3 100755 --- a/bin/runner.js +++ b/bin/runner.js @@ -165,6 +165,12 @@ var argv = yargs type: "string", default: undefined }, + 'e': { + alias: 'exclude', + describe: Constants.cliMessages.RUN.EXCLUDE, + type: "string", + default: undefined + }, 's': { alias: ['specs', 'spec'], describe: Constants.cliMessages.RUN.SPECS_DESCRIPTION, diff --git a/bin/templates/configTemplate.js b/bin/templates/configTemplate.js index 08349830..7b3556be 100644 --- a/bin/templates/configTemplate.js +++ b/bin/templates/configTemplate.js @@ -55,6 +55,7 @@ module.exports = function () { "cypress_proj_dir" : "/path/to/directory-that-contains--file", "project_name": "project-name", "build_name": "build-name", + "exclude": [], "parallels": "Here goes the number of parallels you want to run", "npm_dependencies": { }, diff --git a/test/unit/bin/helpers/archiver.js b/test/unit/bin/helpers/archiver.js new file mode 100644 index 00000000..07f9e239 --- /dev/null +++ b/test/unit/bin/helpers/archiver.js @@ -0,0 +1,57 @@ +const chai = require("chai"), + rewire = require("rewire"), + chaiAsPromised = require("chai-as-promised"); + +const utils = require("../../../../bin/helpers/utils"), + Constants = require("../../../../bin/helpers/constants"), + logger = require("../../../../bin/helpers/logger").winstonLogger; + +chai.use(chaiAsPromised); +logger.transports["console.info"].silent = true; + +const archiver = rewire("../../../../bin/helpers/archiver"); + +_getFilesToIgnore = archiver.__get__("getFilesToIgnore"); + +describe("archiver.js", () => { + + describe("getFilesToIgnore", () => { + it("no args, no exclude in runSettings", () => { + chai.expect(_getFilesToIgnore({}, undefined)).to.be.eql(Constants.filesToIgnoreWhileUploading); + }); + + it("args passed, no exclude in runSettings", () => { + let excludeFiles = "file1.js, file2.json"; + let argsToArray = utils.fixCommaSeparatedString(excludeFiles).split(','); + chai.expect(_getFilesToIgnore({}, excludeFiles)).to.be.eql(Constants.filesToIgnoreWhileUploading.concat(argsToArray)); + + excludeFiles = "file1.js,file2.json"; + argsToArray = utils.fixCommaSeparatedString(excludeFiles).split(','); + chai.expect(_getFilesToIgnore({}, excludeFiles)).to.be.eql(Constants.filesToIgnoreWhileUploading.concat(argsToArray)); + + excludeFiles = " file1.js , file2.json "; + argsToArray = utils.fixCommaSeparatedString(excludeFiles).split(','); + chai.expect(_getFilesToIgnore({}, excludeFiles)).to.be.eql(Constants.filesToIgnoreWhileUploading.concat(argsToArray)); + }); + + it("args passed, exclude added in runSettings", () => { + // args preceed over config file + let excludeFiles = "file1.js, file2.json "; + let argsToArray = utils.fixCommaSeparatedString(excludeFiles).split(','); + + let runSettings = { exclude: [] }; + chai.expect(_getFilesToIgnore(runSettings, excludeFiles)).to.be.eql(Constants.filesToIgnoreWhileUploading.concat(argsToArray)); + + runSettings = { exclude: ["sample1.js", "sample2.json"] }; + chai.expect(_getFilesToIgnore(runSettings, excludeFiles)).to.be.eql(Constants.filesToIgnoreWhileUploading.concat(argsToArray)); + }); + + it("no args, exclude added in runSettings", () => { + let runSettings = { exclude: [] }; + chai.expect(_getFilesToIgnore(runSettings, undefined)).to.be.eql(Constants.filesToIgnoreWhileUploading); + + runSettings = { exclude: ["sample1.js", "sample2.json"] }; + chai.expect(_getFilesToIgnore(runSettings, undefined)).to.be.eql(Constants.filesToIgnoreWhileUploading.concat(runSettings.exclude)); + }); + }); +});