Skip to content

Commit b6d7e5f

Browse files
authored
Merge pull request #29 from browserstack/CYP_175_parallelisation_support
Cyp 175 parallelisation support
2 parents 99e2205 + c320593 commit b6d7e5f

File tree

10 files changed

+404
-13
lines changed

10 files changed

+404
-13
lines changed

bin/commands/runs.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,13 @@ module.exports = function run(args) {
1515
return utils.validateBstackJson(bsConfigPath).then(function (bsConfig) {
1616
utils.setUsageReportingFlag(bsConfig, args.disableUsageReporting);
1717

18-
// Validate browserstack.json values
19-
return capabilityHelper.validate(bsConfig).then(function (validated) {
18+
// Validate browserstack.json values and parallels specified via arguments
19+
return capabilityHelper.validate(bsConfig, args).then(function (validated) {
2020
logger.info(validated);
2121

22+
// accept the number of parallels
23+
utils.setParallels(bsConfig, args);
24+
2225
// Archive the spec files
2326
return archiver.archive(bsConfig.run_settings, config.fileName).then(function (data) {
2427

@@ -57,7 +60,12 @@ module.exports = function run(args) {
5760
}).catch(function (err) {
5861
// browerstack.json is not valid
5962
logger.error(err);
60-
logger.error(Constants.validationMessages.NOT_VALID);
63+
64+
// display browserstack.json is not valid only if validation of browserstack.json field has failed, otherwise display just the error message
65+
// If parallels specified in arguments are invalid do not display browserstack.json is invalid message
66+
if (!(err === Constants.validationMessages.INVALID_PARALLELS_CONFIGURATION && !utils.isUndefined(args.parallels))) {
67+
logger.error(Constants.validationMessages.NOT_VALID);
68+
}
6169

6270
let error_code = utils.getErrorCodeFromMsg(err);
6371
utils.sendUsageReport(bsConfig, args, `${err}\n${Constants.validationMessages.NOT_VALID}`, Constants.messageTypes.ERROR, error_code);

bin/helpers/capabilityHelper.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const logger = require("./logger").winstonLogger,
22
Constants = require("./constants"),
3+
Utils = require("./utils"),
34
fs = require('fs'),
45
path = require('path');
56

@@ -66,6 +67,7 @@ const caps = (bsConfig, zip) => {
6667
obj.customBuildName = bsConfig.run_settings.customBuildName || bsConfig.run_settings.build_name;
6768
obj.callbackURL = bsConfig.run_settings.callback_url;
6869
obj.projectNotifyURL = bsConfig.run_settings.project_notify_URL;
70+
obj.parallels = bsConfig.run_settings.parallels;
6971
}
7072

7173
if (obj.project) logger.log(`Project name is: ${obj.project}`);
@@ -76,12 +78,14 @@ const caps = (bsConfig, zip) => {
7678

7779
if (obj.projectNotifyURL) logger.info(`Project notify URL is: ${obj.projectNotifyURL}`);
7880

81+
if (obj.parallels) logger.info(`Parallels limit specified: ${obj.parallels}`);
82+
7983
var data = JSON.stringify(obj);
8084
resolve(data);
8185
})
8286
}
8387

84-
const validate = (bsConfig) => {
88+
const validate = (bsConfig, args) => {
8589
return new Promise(function(resolve, reject){
8690
if (!bsConfig) reject(Constants.validationMessages.EMPTY_BROWSERSTACK_JSON);
8791

@@ -91,7 +95,13 @@ const validate = (bsConfig) => {
9195

9296
if (!bsConfig.run_settings) reject(Constants.validationMessages.EMPTY_RUN_SETTINGS);
9397

94-
if(!bsConfig.run_settings.cypress_proj_dir) reject(Constants.validationMessages.EMPTY_SPEC_FILES);
98+
if (!bsConfig.run_settings.cypress_proj_dir) reject(Constants.validationMessages.EMPTY_SPEC_FILES);
99+
100+
// validate parallels specified in browserstack.json if parallels are not specified via arguments
101+
if (!Utils.isUndefined(args) && Utils.isUndefined(args.parallels) && !Utils.isParallelValid(bsConfig.run_settings.parallels)) reject(Constants.validationMessages.INVALID_PARALLELS_CONFIGURATION);
102+
103+
// if parallels specified via arguments validate only arguments
104+
if (!Utils.isUndefined(args) && !Utils.isUndefined(args.parallels) && !Utils.isParallelValid(args.parallels)) reject(Constants.validationMessages.INVALID_PARALLELS_CONFIGURATION);
95105

96106
if (!fs.existsSync(path.join(bsConfig.run_settings.cypress_proj_dir, 'cypress.json'))) reject(Constants.validationMessages.CYPRESS_JSON_NOT_FOUND + bsConfig.run_settings.cypress_proj_dir);
97107

bin/helpers/constants.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const validationMessages = {
2424
NOT_VALID: "browerstack.json is not valid",
2525
NOT_VALID_JSON: "browerstack.json is not a valid json",
2626
INVALID_EXTENSION: "Invalid files, please remove these files and try again.",
27+
INVALID_PARALLELS_CONFIGURATION: "Invalid value specified for parallels to use. Maximum parallels to use should be a number greater than 0.",
2728
CYPRESS_JSON_NOT_FOUND: "cypress.json file is not found at cypress_proj_dir path ",
2829
INVALID_CYPRESS_JSON: "cypress.json is not a valid json"
2930
};
@@ -48,6 +49,7 @@ const cliMessages = {
4849
STOP_MESSAGE: "Stopping build with given buildId "
4950
},
5051
RUN: {
52+
PARALLEL_DESC: "The maximum number of parallels to use to run your test suite",
5153
INFO: "Run your tests on BrowserStack.",
5254
DESC: "Path to BrowserStack config",
5355
CONFIG_DEMAND: "config file is required"

bin/helpers/utils.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,20 @@ exports.setUsageReportingFlag = (bsConfig, disableUsageReporting) => {
7070
}
7171
}
7272

73+
exports.setParallels = (bsConfig, args) => {
74+
if (!this.isUndefined(args.parallels)) {
75+
bsConfig['run_settings']['parallels'] = args.parallels;
76+
}
77+
}
78+
79+
exports.isUndefined = value => (value === undefined || value === null);
80+
81+
exports.isFloat = value => (Number(value) && Number(value) % 1 !== 0);
82+
83+
exports.isParallelValid = (value) => {
84+
return this.isUndefined(value) || !(isNaN(value) || this.isFloat(value) || parseInt(value, 10) === 0 || parseInt(value, 10) < -1);
85+
}
86+
7387
exports.getUserAgent = () => {
7488
return `BStack-Cypress-CLI/1.x (${os.arch()}/${os.platform()}/${os.release()})`;
7589
}

bin/runner.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ var argv = yargs
101101
})
102102
.command('run', Constants.cliMessages.RUN.INFO, function(yargs) {
103103
argv = yargs
104-
.usage('usage: $0 build')
104+
.usage('usage: $0 run <options>')
105105
.options({
106106
'cf': {
107107
alias: 'config-file',
@@ -117,6 +117,12 @@ var argv = yargs
117117
description: Constants.cliMessages.COMMON.DISABLE_USAGE_REPORTING,
118118
type: "boolean"
119119
},
120+
'p': {
121+
alias: 'parallels',
122+
describe: Constants.cliMessages.RUN.PARALLEL_DESC,
123+
type: "number",
124+
default: undefined
125+
}
120126
})
121127
.help('help')
122128
.wrap(null)

bin/templates/configTemplate.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ module.exports = function () {
1515
"cypress_proj_dir" : "/path/to/cypress.json",
1616
"project_name": "project-name",
1717
"build_name": "build-name",
18+
"parallels": "Here goes the number of parallels you want to run",
1819
"npm_dependencies": {
1920
}
2021
},

test/unit/bin/commands/runs.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ describe("runs", () => {
134134

135135
beforeEach(() => {
136136
sandbox = sinon.createSandbox();
137+
setParallelsStub = sandbox.stub();
137138
validateBstackJsonStub = sandbox.stub();
138139
setUsageReportingFlagStub = sandbox.stub().returns(undefined);
139140
sendUsageReportStub = sandbox.stub().callsFake(function () {
@@ -158,6 +159,7 @@ describe("runs", () => {
158159
"../helpers/utils": {
159160
validateBstackJson: validateBstackJsonStub,
160161
sendUsageReport: sendUsageReportStub,
162+
setParallels: setParallelsStub,
161163
setUsageReportingFlag: setUsageReportingFlagStub,
162164
},
163165
"../helpers/capabilityHelper": {
@@ -180,6 +182,7 @@ describe("runs", () => {
180182
chai.assert.fail("Promise error");
181183
})
182184
.catch((error) => {
185+
sinon.assert.calledOnce(setParallelsStub)
183186
sinon.assert.calledOnce(validateBstackJsonStub);
184187
sinon.assert.calledOnce(capabilityValidatorStub);
185188
sinon.assert.calledOnce(archiverStub);
@@ -203,6 +206,7 @@ describe("runs", () => {
203206
beforeEach(() => {
204207
sandbox = sinon.createSandbox();
205208
validateBstackJsonStub = sandbox.stub();
209+
setParallelsStub = sandbox.stub();
206210
setUsageReportingFlagStub = sandbox.stub().returns(undefined);
207211
sendUsageReportStub = sandbox.stub().callsFake(function () {
208212
return "end";
@@ -227,6 +231,7 @@ describe("runs", () => {
227231
"../helpers/utils": {
228232
validateBstackJson: validateBstackJsonStub,
229233
sendUsageReport: sendUsageReportStub,
234+
setParallels: setParallelsStub,
230235
setUsageReportingFlag: setUsageReportingFlagStub,
231236
},
232237
"../helpers/capabilityHelper": {
@@ -253,6 +258,7 @@ describe("runs", () => {
253258
chai.assert.fail("Promise error");
254259
})
255260
.catch((error) => {
261+
sinon.assert.calledOnce(setParallelsStub);
256262
sinon.assert.calledOnce(validateBstackJsonStub);
257263
sinon.assert.calledOnce(capabilityValidatorStub);
258264
sinon.assert.calledOnce(archiverStub);
@@ -280,6 +286,7 @@ describe("runs", () => {
280286
beforeEach(() => {
281287
sandbox = sinon.createSandbox();
282288
validateBstackJsonStub = sandbox.stub();
289+
setParallelsStub = sandbox.stub();
283290
setUsageReportingFlagStub = sandbox.stub().returns(undefined);
284291
sendUsageReportStub = sandbox.stub().callsFake(function () {
285292
return "end";
@@ -305,6 +312,7 @@ describe("runs", () => {
305312
"../helpers/utils": {
306313
validateBstackJson: validateBstackJsonStub,
307314
sendUsageReport: sendUsageReportStub,
315+
setParallels: setParallelsStub,
308316
setUsageReportingFlag: setUsageReportingFlagStub,
309317
},
310318
"../helpers/capabilityHelper": {
@@ -339,6 +347,7 @@ describe("runs", () => {
339347
.catch((error) => {
340348
sinon.assert.calledOnce(validateBstackJsonStub);
341349
sinon.assert.calledOnce(capabilityValidatorStub);
350+
sinon.assert.calledOnce(setParallelsStub);
342351
sinon.assert.calledOnce(archiverStub);
343352
sinon.assert.calledOnce(setUsageReportingFlagStub);
344353
sinon.assert.calledOnce(zipUploadStub);
@@ -368,6 +377,7 @@ describe("runs", () => {
368377
beforeEach(() => {
369378
sandbox = sinon.createSandbox();
370379
validateBstackJsonStub = sandbox.stub();
380+
setParallelsStub = sandbox.stub();
371381
setUsageReportingFlagStub = sandbox.stub().returns(undefined);
372382
sendUsageReportStub = sandbox.stub().callsFake(function () {
373383
return "end";
@@ -394,6 +404,7 @@ describe("runs", () => {
394404
validateBstackJson: validateBstackJsonStub,
395405
sendUsageReport: sendUsageReportStub,
396406
setUsageReportingFlag: setUsageReportingFlagStub,
407+
setParallels: setParallelsStub,
397408
},
398409
"../helpers/capabilityHelper": {
399410
validate: capabilityValidatorStub,
@@ -427,6 +438,7 @@ describe("runs", () => {
427438
.catch((error) => {
428439
sinon.assert.calledOnce(validateBstackJsonStub);
429440
sinon.assert.calledOnce(capabilityValidatorStub);
441+
sinon.assert.calledOnce(setParallelsStub);
430442
sinon.assert.calledOnce(archiverStub);
431443
sinon.assert.calledOnce(setUsageReportingFlagStub);
432444
sinon.assert.calledOnce(zipUploadStub);

0 commit comments

Comments
 (0)