Skip to content

Commit 0c2e7d4

Browse files
Merge branch 'master' of github.com:browserstack/browserstack-cypress-cli into bug_fixes
2 parents 92eecbc + 832af98 commit 0c2e7d4

File tree

11 files changed

+515
-25
lines changed

11 files changed

+515
-25
lines changed

bin/commands/runs.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ module.exports = function run(args) {
2626
// accept the build name from command line if provided
2727
utils.setBuildName(bsConfig, args);
2828

29+
// accept the specs list from command line if provided
30+
utils.setUserSpecs(bsConfig, args);
31+
32+
// accept the env list from command line and set it
33+
utils.setTestEnvs(bsConfig, args);
34+
2935
//accept the local from env variable if provided
3036
utils.setLocal(bsConfig);
3137

@@ -40,7 +46,7 @@ module.exports = function run(args) {
4046
utils.setParallels(bsConfig, args);
4147

4248
// Archive the spec files
43-
return archiver.archive(bsConfig.run_settings, config.fileName).then(function (data) {
49+
return archiver.archive(bsConfig.run_settings, config.fileName, args.exclude).then(function (data) {
4450

4551
// Uploaded zip file
4652
return zipUploader.zipUpload(bsConfig, config.fileName).then(function (zip) {
@@ -50,7 +56,7 @@ module.exports = function run(args) {
5056
let message = `${data.message}! ${Constants.userMessages.BUILD_CREATED} with build id: ${data.build_id}`;
5157
let dashboardLink = `${Constants.userMessages.VISIT_DASHBOARD} ${config.dashboardUrl}${data.build_id}`;
5258
utils.exportResults(data.build_id, `${config.dashboardUrl}${data.build_id}`);
53-
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)) {
59+
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)) {
5460
logger.warn(Constants.userMessages.NO_PARALLELS);
5561
}
5662

bin/helpers/archiver.js

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22
const fs = require("fs");
33

44
const archiver = require("archiver"),
5-
logger = require("./logger").winstonLogger;
5+
Constants = require('../helpers/constants'),
6+
logger = require("./logger").winstonLogger,
7+
utils = require('../helpers/utils');
68

7-
const archiveSpecs = (runSettings, filePath) => {
9+
const archiveSpecs = (runSettings, filePath, excludeFiles) => {
810
return new Promise(function (resolve, reject) {
911
var output = fs.createWriteStream(filePath);
1012

@@ -36,9 +38,10 @@ const archiveSpecs = (runSettings, filePath) => {
3638

3739
archive.pipe(output);
3840

39-
let allowedFileTypes = [ 'js', 'json', 'txt', 'ts', 'feature', 'features', 'pdf', 'jpg', 'jpeg', 'png', 'zip' ];
40-
allowedFileTypes.forEach(fileType => {
41-
archive.glob(`**/*.${fileType}`, { cwd: cypressFolderPath, matchBase: true, ignore: ['**/node_modules/**', './node_modules/**', 'package-lock.json', 'package.json', 'browserstack-package.json', 'tests.zip'] });
41+
let ignoreFiles = getFilesToIgnore(runSettings, excludeFiles);
42+
43+
Constants.allowedFileTypes.forEach(fileType => {
44+
archive.glob(`**/*.${fileType}`, { cwd: cypressFolderPath, matchBase: true, ignore: ignoreFiles });
4245
});
4346

4447
let packageJSON = {};
@@ -60,4 +63,21 @@ const archiveSpecs = (runSettings, filePath) => {
6063
});
6164
}
6265

66+
const getFilesToIgnore = (runSettings, excludeFiles) => {
67+
let ignoreFiles = Constants.filesToIgnoreWhileUploading;
68+
69+
// exclude files asked by the user
70+
// args will take precedence over config file
71+
if (!utils.isUndefined(excludeFiles)) {
72+
let excludePatterns = utils.fixCommaSeparatedString(excludeFiles).split(',');
73+
ignoreFiles = ignoreFiles.concat(excludePatterns);
74+
logger.info(`Excluding files matching: ${JSON.stringify(excludePatterns)}`);
75+
} else if (!utils.isUndefined(runSettings.exclude) && runSettings.exclude.length) {
76+
ignoreFiles = ignoreFiles.concat(runSettings.exclude);
77+
logger.info(`Excluding files matching: ${JSON.stringify(runSettings.exclude)}`);
78+
}
79+
80+
return ignoreFiles;
81+
}
82+
6383
exports.archive = archiveSpecs

bin/helpers/capabilityHelper.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,17 @@ const caps = (bsConfig, zip) => {
6767
obj.callbackURL = bsConfig.run_settings.callback_url;
6868
obj.projectNotifyURL = bsConfig.run_settings.project_notify_URL;
6969
obj.parallels = bsConfig.run_settings.parallels;
70+
71+
if (!Utils.isUndefined(bsConfig.run_settings.specs)){
72+
obj.specs = bsConfig.run_settings.specs;
73+
}
74+
75+
if (!Utils.isUndefined(bsConfig.run_settings.env)){
76+
obj.env = bsConfig.run_settings.env;
77+
}
7078
}
7179

72-
if(obj.parallels === Constants.constants.DEFAULT_PARALLEL_MESSAGE) obj.parallels = undefined
80+
if(obj.parallels === Constants.cliMessages.RUN.DEFAULT_PARALLEL_MESSAGE) obj.parallels = undefined
7381

7482
if (obj.project) logger.log(`Project name is: ${obj.project}`);
7583

bin/helpers/constants.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,11 @@ const cliMessages = {
6060
INFO: "Run your tests on BrowserStack.",
6161
DESC: "Path to BrowserStack config",
6262
CONFIG_DEMAND: "config file is required",
63-
BUILD_NAME: "The build name you want to use to name your test runs"
63+
BUILD_NAME: "The build name you want to use to name your test runs",
64+
EXCLUDE: "Exclude files matching a pattern from zipping and uploading",
65+
DEFAULT_PARALLEL_MESSAGE: "Here goes the number of parallels you want to run",
66+
SPECS_DESCRIPTION: 'Specify the spec files to run',
67+
ENV_DESCRIPTION: "Specify the environment variables for your spec files"
6468
},
6569
COMMON: {
6670
DISABLE_USAGE_REPORTING: "Disable usage reporting",
@@ -79,14 +83,15 @@ const messageTypes = {
7983
NULL: null
8084
}
8185

82-
const constants = {
83-
DEFAULT_PARALLEL_MESSAGE: "Here goes the number of parallels you want to run"
84-
}
86+
const allowedFileTypes = ['js', 'json', 'txt', 'ts', 'feature', 'features', 'pdf', 'jpg', 'jpeg', 'png', 'zip'];
87+
88+
const filesToIgnoreWhileUploading = ['node_modules/**', 'package-lock.json', 'package.json', 'browserstack-package.json', 'tests.zip']
8589

8690
module.exports = Object.freeze({
8791
userMessages,
8892
cliMessages,
8993
validationMessages,
9094
messageTypes,
91-
constants
95+
allowedFileTypes,
96+
filesToIgnoreWhileUploading
9297
});

bin/helpers/utils.js

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -140,22 +140,43 @@ exports.setBuildName = (bsConfig, args) => {
140140
}
141141
};
142142

143-
exports.isUndefined = (value) => value === undefined || value === null;
143+
// specs can be passed from bstack configuration file
144+
// specs can be passed via command line args as a string
145+
// command line args takes precedence over config
146+
exports.setUserSpecs = (bsConfig, args) => {
147+
let bsConfigSpecs = bsConfig.run_settings.specs;
148+
149+
if (!this.isUndefined(args.specs)) {
150+
bsConfig.run_settings.specs = this.fixCommaSeparatedString(args.specs);
151+
} else if (!this.isUndefined(bsConfigSpecs) && Array.isArray(bsConfigSpecs)) {
152+
bsConfig.run_settings.specs = bsConfigSpecs.join(',');
153+
} else if (!this.isUndefined(bsConfigSpecs) && typeof(bsConfigSpecs) == "string") {
154+
bsConfig.run_settings.specs = this.fixCommaSeparatedString(bsConfigSpecs);
155+
} else {
156+
bsConfig.run_settings.specs = null;
157+
}
158+
}
159+
160+
// env option must be set only from command line args as a string
161+
exports.setTestEnvs = (bsConfig, args) => {
162+
if (!this.isUndefined(args.env)) {
163+
bsConfig.run_settings.env = this.fixCommaSeparatedString(args.env);
164+
} else {
165+
bsConfig.run_settings.env = null;
166+
}
167+
}
168+
169+
exports.fixCommaSeparatedString = (string) => {
170+
return string.split(/\s{0,},\s+/).join(',');
171+
}
172+
173+
exports.isUndefined = value => (value === undefined || value === null);
144174

145175
exports.isFloat = (value) => Number(value) && Number(value) % 1 !== 0;
146176

147177
exports.isParallelValid = (value) => {
148-
return (
149-
this.isUndefined(value) ||
150-
!(
151-
isNaN(value) ||
152-
this.isFloat(value) ||
153-
parseInt(value, 10) === 0 ||
154-
parseInt(value, 10) < -1
155-
) ||
156-
value === Constants.constants.DEFAULT_PARALLEL_MESSAGE
157-
);
158-
};
178+
return this.isUndefined(value) || !(isNaN(value) || this.isFloat(value) || parseInt(value, 10) === 0 || parseInt(value, 10) < -1) || value === Constants.cliMessages.RUN.DEFAULT_PARALLEL_MESSAGE;
179+
}
159180

160181
exports.getUserAgent = () => {
161182
return `BStack-Cypress-CLI/1.3.0 (${os.arch()}/${os.platform()}/${os.release()})`;

bin/runner.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,23 @@ var argv = yargs
165165
type: "string",
166166
default: undefined
167167
},
168+
'e': {
169+
alias: 'exclude',
170+
describe: Constants.cliMessages.RUN.EXCLUDE,
171+
type: "string",
172+
default: undefined
173+
},
174+
's': {
175+
alias: ['specs', 'spec'],
176+
describe: Constants.cliMessages.RUN.SPECS_DESCRIPTION,
177+
type: "string",
178+
default: undefined
179+
},
180+
'env': {
181+
describe: Constants.cliMessages.RUN.ENV_DESCRIPTION,
182+
type: "string",
183+
default: undefined
184+
},
168185
'disable-npm-warning': {
169186
default: false,
170187
description: Constants.cliMessages.COMMON.NO_NPM_WARNING,

bin/templates/configTemplate.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ module.exports = function () {
5555
"cypress_proj_dir" : "/path/to/directory-that-contains-<cypress.json>-file",
5656
"project_name": "project-name",
5757
"build_name": "build-name",
58+
"exclude": [],
5859
"parallels": "Here goes the number of parallels you want to run",
5960
"npm_dependencies": {
6061
},

test/unit/bin/commands/runs.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ describe("runs", () => {
8585
setUsernameStub = sandbox.stub();
8686
setAccessKeyStub = sandbox.stub();
8787
setBuildNameStub = sandbox.stub();
88+
setUserSpecsStub = sandbox.stub();
89+
setTestEnvsStub = sandbox.stub();
8890
getConfigPathStub = sandbox.stub();
8991
setUsageReportingFlagStub = sandbox.stub().returns(undefined);
9092
sendUsageReportStub = sandbox.stub().callsFake(function () {
@@ -116,6 +118,8 @@ describe("runs", () => {
116118
setUsername: setUsernameStub,
117119
setAccessKey: setAccessKeyStub,
118120
setBuildName: setBuildNameStub,
121+
setUserSpecs: setUserSpecsStub,
122+
setTestEnvs: setTestEnvsStub,
119123
getConfigPath: getConfigPathStub,
120124
setLocal: setLocalStub,
121125
setLocalIdentifier: setLocalIdentifierStub,
@@ -165,6 +169,8 @@ describe("runs", () => {
165169
setAccessKeyStub = sandbox.stub();
166170
getConfigPathStub = sandbox.stub();
167171
setBuildNameStub = sandbox.stub();
172+
setUserSpecsStub = sandbox.stub();
173+
setTestEnvsStub = sandbox.stub();
168174
validateBstackJsonStub = sandbox.stub();
169175
setUsageReportingFlagStub = sandbox.stub().returns(undefined);
170176
sendUsageReportStub = sandbox.stub().callsFake(function () {
@@ -196,6 +202,8 @@ describe("runs", () => {
196202
setUsername: setUsernameStub,
197203
setAccessKey: setAccessKeyStub,
198204
setBuildName: setBuildNameStub,
205+
setUserSpecs: setUserSpecsStub,
206+
setTestEnvs: setTestEnvsStub,
199207
setUsageReportingFlag: setUsageReportingFlagStub,
200208
getConfigPath: getConfigPathStub,
201209
setLocal: setLocalStub,
@@ -255,6 +263,8 @@ describe("runs", () => {
255263
setUsernameStub = sandbox.stub();
256264
setAccessKeyStub = sandbox.stub();
257265
setBuildNameStub = sandbox.stub();
266+
setUserSpecsStub = sandbox.stub();
267+
setTestEnvsStub = sandbox.stub();
258268
getConfigPathStub = sandbox.stub();
259269
setUsageReportingFlagStub = sandbox.stub().returns(undefined);
260270
sendUsageReportStub = sandbox.stub().callsFake(function () {
@@ -287,6 +297,8 @@ describe("runs", () => {
287297
setUsername: setUsernameStub,
288298
setAccessKey: setAccessKeyStub,
289299
setBuildName: setBuildNameStub,
300+
setUserSpecs: setUserSpecsStub,
301+
setTestEnvs: setTestEnvsStub,
290302
setUsageReportingFlag: setUsageReportingFlagStub,
291303
getConfigPath: getConfigPathStub,
292304
setLocal: setLocalStub,
@@ -353,6 +365,8 @@ describe("runs", () => {
353365
setUsernameStub = sandbox.stub();
354366
setAccessKeyStub = sandbox.stub();
355367
setBuildNameStub = sandbox.stub();
368+
setUserSpecsStub = sandbox.stub();
369+
setTestEnvsStub = sandbox.stub();
356370
getConfigPathStub = sandbox.stub();
357371
setUsageReportingFlagStub = sandbox.stub().returns(undefined);
358372
sendUsageReportStub = sandbox.stub().callsFake(function () {
@@ -386,6 +400,8 @@ describe("runs", () => {
386400
setUsername: setUsernameStub,
387401
setAccessKey: setAccessKeyStub,
388402
setBuildName: setBuildNameStub,
403+
setUserSpecs: setUserSpecsStub,
404+
setTestEnvs: setTestEnvsStub,
389405
setUsageReportingFlag: setUsageReportingFlagStub,
390406
getConfigPath: getConfigPathStub,
391407
setLocal: setLocalStub,
@@ -463,6 +479,8 @@ describe("runs", () => {
463479
setUsernameStub = sandbox.stub();
464480
setAccessKeyStub = sandbox.stub();
465481
setBuildNameStub = sandbox.stub();
482+
setUserSpecsStub = sandbox.stub();
483+
setTestEnvsStub = sandbox.stub();
466484
getConfigPathStub = sandbox.stub();
467485
setUsageReportingFlagStub = sandbox.stub().returns(undefined);
468486
sendUsageReportStub = sandbox.stub().callsFake(function () {
@@ -499,6 +517,8 @@ describe("runs", () => {
499517
setUsername: setUsernameStub,
500518
setAccessKey: setAccessKeyStub,
501519
setBuildName: setBuildNameStub,
520+
setUserSpecs: setUserSpecsStub,
521+
setTestEnvs: setTestEnvsStub,
502522
setUsageReportingFlag: setUsageReportingFlagStub,
503523
setParallels: setParallelsStub,
504524
getConfigPath: getConfigPathStub,

test/unit/bin/helpers/archiver.js

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
const chai = require("chai"),
2+
rewire = require("rewire"),
3+
chaiAsPromised = require("chai-as-promised");
4+
5+
const utils = require("../../../../bin/helpers/utils"),
6+
Constants = require("../../../../bin/helpers/constants"),
7+
logger = require("../../../../bin/helpers/logger").winstonLogger;
8+
9+
chai.use(chaiAsPromised);
10+
logger.transports["console.info"].silent = true;
11+
12+
const archiver = rewire("../../../../bin/helpers/archiver");
13+
14+
_getFilesToIgnore = archiver.__get__("getFilesToIgnore");
15+
16+
describe("archiver.js", () => {
17+
18+
describe("getFilesToIgnore", () => {
19+
it("no args, no exclude in runSettings", () => {
20+
chai.expect(_getFilesToIgnore({}, undefined)).to.be.eql(Constants.filesToIgnoreWhileUploading);
21+
});
22+
23+
it("args passed, no exclude in runSettings", () => {
24+
let excludeFiles = "file1.js, file2.json";
25+
let argsToArray = utils.fixCommaSeparatedString(excludeFiles).split(',');
26+
chai.expect(_getFilesToIgnore({}, excludeFiles)).to.be.eql(Constants.filesToIgnoreWhileUploading.concat(argsToArray));
27+
28+
excludeFiles = "file1.js,file2.json";
29+
argsToArray = utils.fixCommaSeparatedString(excludeFiles).split(',');
30+
chai.expect(_getFilesToIgnore({}, excludeFiles)).to.be.eql(Constants.filesToIgnoreWhileUploading.concat(argsToArray));
31+
32+
excludeFiles = " file1.js , file2.json ";
33+
argsToArray = utils.fixCommaSeparatedString(excludeFiles).split(',');
34+
chai.expect(_getFilesToIgnore({}, excludeFiles)).to.be.eql(Constants.filesToIgnoreWhileUploading.concat(argsToArray));
35+
});
36+
37+
it("args passed, exclude added in runSettings", () => {
38+
// args preceed over config file
39+
let excludeFiles = "file1.js, file2.json ";
40+
let argsToArray = utils.fixCommaSeparatedString(excludeFiles).split(',');
41+
42+
let runSettings = { exclude: [] };
43+
chai.expect(_getFilesToIgnore(runSettings, excludeFiles)).to.be.eql(Constants.filesToIgnoreWhileUploading.concat(argsToArray));
44+
45+
runSettings = { exclude: ["sample1.js", "sample2.json"] };
46+
chai.expect(_getFilesToIgnore(runSettings, excludeFiles)).to.be.eql(Constants.filesToIgnoreWhileUploading.concat(argsToArray));
47+
});
48+
49+
it("no args, exclude added in runSettings", () => {
50+
let runSettings = { exclude: [] };
51+
chai.expect(_getFilesToIgnore(runSettings, undefined)).to.be.eql(Constants.filesToIgnoreWhileUploading);
52+
53+
runSettings = { exclude: ["sample1.js", "sample2.json"] };
54+
chai.expect(_getFilesToIgnore(runSettings, undefined)).to.be.eql(Constants.filesToIgnoreWhileUploading.concat(runSettings.exclude));
55+
});
56+
});
57+
});

0 commit comments

Comments
 (0)