Skip to content

Commit 2e24fab

Browse files
committed
Merge branch 'master' of https://github.com/browserstack/browserstack-cypress-cli into CYP_394_avoid_node_modules
2 parents 1a08e89 + 22c892e commit 2e24fab

File tree

9 files changed

+240
-27
lines changed

9 files changed

+240
-27
lines changed

bin/commands/runs.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ module.exports = function run(args) {
4141
return build.createBuild(bsConfig, zip).then(function (data) {
4242
let message = `${data.message}! ${Constants.userMessages.BUILD_CREATED} with build id: ${data.build_id}`;
4343
let dashboardLink = `${Constants.userMessages.VISIT_DASHBOARD} ${config.dashboardUrl}${data.build_id}`;
44+
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)) {
45+
logger.warn(Constants.userMessages.NO_PARALLELS);
46+
}
47+
48+
if(!args.disableNpmWarning && bsConfig.run_settings.npm_dependencies && Object.keys(bsConfig.run_settings.npm_dependencies).length <= 0) logger.warn(Constants.userMessages.NO_NPM_DEPENDENCIES);
49+
4450
logger.info(message);
4551
logger.info(dashboardLink);
4652
utils.sendUsageReport(bsConfig, args, `${message}\n${dashboardLink}`, Constants.messageTypes.SUCCESS, null);

bin/helpers/archiver.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ const archiveSpecs = (runSettings, filePath) => {
3636

3737
archive.pipe(output);
3838

39-
let allowedFileTypes = [ 'js', 'json', 'txt', 'ts', 'feature', 'features' ];
39+
let allowedFileTypes = [ 'js', 'json', 'txt', 'ts', 'feature', 'features', 'pdf', 'jpg', 'jpeg', 'png', 'zip' ];
4040
allowedFileTypes.forEach(fileType => {
41-
archive.glob(`**/*.${fileType}`, { cwd: cypressFolderPath, matchBase: true, ignore: ['**/node_modules/**', './node_modules/**', 'package-lock.json', 'package.json', 'browserstack-package.json'] });
41+
archive.glob(`**/*.${fileType}`, { cwd: cypressFolderPath, matchBase: true, ignore: ['**/node_modules/**', './node_modules/**', 'package-lock.json', 'package.json', 'browserstack-package.json', 'tests.zip'] });
4242
});
4343

4444
let packageJSON = {};

bin/helpers/capabilityHelper.js

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,7 @@ const caps = (bsConfig, zip) => {
4747

4848
// Local Identifier
4949
obj.localIdentifier = null;
50-
if (obj.local === true && (bsConfig.connection_settings.localIdentifier || bsConfig.connection_settings.local_identifier))
51-
{
50+
if (obj.local === true && (bsConfig.connection_settings.localIdentifier || bsConfig.connection_settings.local_identifier)) {
5251
obj.localIdentifier = bsConfig.connection_settings.localIdentifier || bsConfig.connection_settings.local_identifier;
5352
logger.log(`Local Identifier is set to: ${obj.localIdentifier}`);
5453
}
@@ -70,6 +69,8 @@ const caps = (bsConfig, zip) => {
7069
obj.parallels = bsConfig.run_settings.parallels;
7170
}
7271

72+
if(obj.parallels === Constants.constants.DEFAULT_PARALLEL_MESSAGE) obj.parallels = undefined
73+
7374
if (obj.project) logger.log(`Project name is: ${obj.project}`);
7475

7576
if (obj.customBuildName) logger.log(`Build name is: ${obj.customBuildName}`);
@@ -86,16 +87,18 @@ const caps = (bsConfig, zip) => {
8687
}
8788

8889
const validate = (bsConfig, args) => {
89-
return new Promise(function(resolve, reject){
90+
return new Promise(function (resolve, reject) {
9091
if (!bsConfig) reject(Constants.validationMessages.EMPTY_BROWSERSTACK_JSON);
9192

9293
if (!bsConfig.auth) reject(Constants.validationMessages.INCORRECT_AUTH_PARAMS);
9394

95+
if( bsConfig.auth.username == "<Your BrowserStack username>" || bsConfig.auth.access_key == "<Your BrowserStack access key>" ) reject(Constants.validationMessages.INVALID_DEFAULT_AUTH_PARAMS);
96+
9497
if (!bsConfig.browsers || bsConfig.browsers.length === 0) reject(Constants.validationMessages.EMPTY_BROWSER_LIST);
9598

9699
if (!bsConfig.run_settings) reject(Constants.validationMessages.EMPTY_RUN_SETTINGS);
97100

98-
if (!bsConfig.run_settings.cypress_proj_dir) reject(Constants.validationMessages.EMPTY_SPEC_FILES);
101+
if (!bsConfig.run_settings.cypress_proj_dir) reject(Constants.validationMessages.EMPTY_CYPRESS_PROJ_DIR);
99102

100103
// validate parallels specified in browserstack.json if parallels are not specified via arguments
101104
if (!Utils.isUndefined(args) && Utils.isUndefined(args.parallels) && !Utils.isParallelValid(bsConfig.run_settings.parallels)) reject(Constants.validationMessages.INVALID_PARALLELS_CONFIGURATION);
@@ -105,10 +108,16 @@ const validate = (bsConfig, args) => {
105108

106109
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);
107110

108-
try{
109-
let cypressJson = fs.readFileSync(path.join(bsConfig.run_settings.cypress_proj_dir, 'cypress.json'))
110-
JSON.parse(cypressJson)
111-
}catch(error){
111+
try {
112+
let cypressJson = fs.readFileSync(path.join(bsConfig.run_settings.cypress_proj_dir, 'cypress.json'));
113+
cypressJson = JSON.parse(cypressJson);
114+
// Cypress Json Base Url & Local true check
115+
if (!Utils.isUndefined(cypressJson.baseUrl) && cypressJson.baseUrl.includes("localhost") && !Utils.getLocalFlag(bsConfig.connection_settings)) reject(Constants.validationMessages.LOCAL_NOT_SET);
116+
117+
// Detect if the user is not using the right directory structure, and throw an error
118+
if (!Utils.isUndefined(cypressJson.integrationFolder) && !Utils.isCypressProjDirValid(bsConfig.run_settings.cypress_proj_dir,cypressJson.integrationFolder)) reject(Constants.validationMessages.INCORRECT_DIRECTORY_STRUCTURE);
119+
120+
} catch (error) {
112121
reject(Constants.validationMessages.INVALID_CYPRESS_JSON)
113122
}
114123

bin/helpers/constants.js

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ const userMessages = {
1212
ZIP_DELETED: "Zip file deleted successfully.",
1313
API_DEPRECATED: "This version of API is deprecated, please use latest version of API.",
1414
FAILED_TO_ZIP: "Failed to zip files.",
15-
VISIT_DASHBOARD: "Visit the Automate dashboard for test reporting:"
15+
VISIT_DASHBOARD: "Visit the Automate dashboard for test reporting:",
16+
NO_PARALLELS: "Your tests will run sequentially. Read more about running your tests in parallel here: https://www.browserstack.com/docs/automate/cypress/run-tests-in-parallel",
17+
NO_NPM_DEPENDENCIES: "No npm dependencies specified. Read more here: https://www.browserstack.com/docs/automate/cypress/npm-packages. You can suppress this warning by using --disable-npm-warning flag."
1618
};
1719

1820
const validationMessages = {
@@ -21,14 +23,17 @@ const validationMessages = {
2123
EMPTY_TEST_SUITE: "Test suite is empty",
2224
EMPTY_BROWSERSTACK_JSON: "Empty browserstack.json",
2325
EMPTY_RUN_SETTINGS: "Empty run settings",
24-
EMPTY_SPEC_FILES: "No spec files specified in run_settings",
26+
EMPTY_CYPRESS_PROJ_DIR: "cypress_proj_dir is not set in run_settings. See https://www.browserstack.com/docs/automate/cypress/sample-tutorial to learn more.",
2527
VALIDATED: "browserstack.json file is validated",
2628
NOT_VALID: "browerstack.json is not valid",
2729
NOT_VALID_JSON: "browerstack.json is not a valid json",
2830
INVALID_EXTENSION: "Invalid files, please remove these files and try again.",
2931
INVALID_PARALLELS_CONFIGURATION: "Invalid value specified for parallels to use. Maximum parallels to use should be a number greater than 0.",
3032
CYPRESS_JSON_NOT_FOUND: "cypress.json file is not found at cypress_proj_dir path ",
31-
INVALID_CYPRESS_JSON: "cypress.json is not a valid json"
33+
INVALID_CYPRESS_JSON: "cypress.json is not a valid json",
34+
INVALID_DEFAULT_AUTH_PARAMS: "Your username and access key are required to run your tests on BrowserStack. Learn more at https://www.browserstack.com/docs/automate/cypress/authentication",
35+
LOCAL_NOT_SET: "To test <baseUrl value> on BrowserStack, you will have to set up Local testing. Read more here: https://www.browserstack.com/docs/automate/cypress/local-testing",
36+
INCORRECT_DIRECTORY_STRUCTURE: "No tests to run. Note that your Cypress tests should be in the same directory where the cypress.json exists."
3237
};
3338

3439
const cliMessages = {
@@ -60,7 +65,8 @@ const cliMessages = {
6065
COMMON: {
6166
DISABLE_USAGE_REPORTING: "Disable usage reporting",
6267
USERNAME: "Your BrowserStack username",
63-
ACCESS_KEY: "Your BrowserStack access key"
68+
ACCESS_KEY: "Your BrowserStack access key",
69+
NO_NPM_WARNING: "No NPM warning if npm_dependencies is empty"
6470
}
6571
}
6672

@@ -73,9 +79,14 @@ const messageTypes = {
7379
NULL: null
7480
}
7581

82+
const constants = {
83+
DEFAULT_PARALLEL_MESSAGE: "Here goes the number of parallels you want to run"
84+
}
85+
7686
module.exports = Object.freeze({
7787
userMessages,
7888
cliMessages,
7989
validationMessages,
8090
messageTypes,
91+
constants
8192
});

bin/helpers/utils.js

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ exports.validateBstackJson = (bsConfigPath) => {
1414
resolve(bsConfig);
1515
}
1616
catch (e) {
17-
reject(e);
17+
reject("Couldn't find the browserstack.json file at \""+ bsConfigPath +"\". Please use --config-file <path to browserstack.json>.");
1818
}
1919
});
2020
}
@@ -34,9 +34,24 @@ exports.getErrorCodeFromMsg = (errMsg) => {
3434
case Constants.validationMessages.EMPTY_RUN_SETTINGS:
3535
errorCode = "bstack_json_invalid_no_run_settings";
3636
break;
37-
case Constants.validationMessages.EMPTY_SPEC_FILES:
38-
errorCode = "bstack_json_invalid_values";
37+
case Constants.validationMessages.EMPTY_CYPRESS_PROJ_DIR:
38+
errorCode = "bstack_json_invalid_no_cypress_proj_dir";
3939
break;
40+
case Constants.validationMessages.INVALID_DEFAULT_AUTH_PARAMS:
41+
errorCode = "bstack_json_default_auth_keys";
42+
break;
43+
case Constants.validationMessages.INVALID_PARALLELS_CONFIGURATION:
44+
errorCode = "invalid_parallels_specified";
45+
break;
46+
case Constants.validationMessages.LOCAL_NOT_SET:
47+
errorCode = "cypress_json_base_url_no_local";
48+
break;
49+
case Constants.validationMessages.INCORRECT_DIRECTORY_STRUCTURE:
50+
errorCode = "invalid_directory_structure";
51+
break;
52+
}
53+
if(errMsg.includes("Please use --config-file <path to browserstack.json>.")){
54+
errorCode = "bstack_json_path_invalid";
4055
}
4156
return errorCode;
4257
}
@@ -100,7 +115,7 @@ exports.isUndefined = value => (value === undefined || value === null);
100115
exports.isFloat = value => (Number(value) && Number(value) % 1 !== 0);
101116

102117
exports.isParallelValid = (value) => {
103-
return this.isUndefined(value) || !(isNaN(value) || this.isFloat(value) || parseInt(value, 10) === 0 || parseInt(value, 10) < -1);
118+
return this.isUndefined(value) || !(isNaN(value) || this.isFloat(value) || parseInt(value, 10) === 0 || parseInt(value, 10) < -1 ) || value === Constants.constants.DEFAULT_PARALLEL_MESSAGE;
104119
}
105120

106121
exports.getUserAgent = () => {
@@ -120,3 +135,17 @@ exports.configCreated = (args) => {
120135
logger.info(message);
121136
this.sendUsageReport(null, args, message, Constants.messageTypes.SUCCESS, null);
122137
}
138+
139+
exports.isCypressProjDirValid = (cypressDir, cypressProjDir) => {
140+
// Getting absolute path
141+
cypressDir = path.resolve(cypressDir);
142+
cypressProjDir = path.resolve(cypressProjDir);
143+
if(cypressProjDir === cypressDir) return true;
144+
let parentTokens = cypressDir.split('/').filter(i => i.length);
145+
let childTokens = cypressProjDir.split('/').filter(i => i.length);
146+
return parentTokens.every((t, i) => childTokens[i] === t);
147+
}
148+
149+
exports.getLocalFlag = (connectionSettings) => {
150+
return !this.isUndefined(connectionSettings) && !this.isUndefined(connectionSettings.local) && connectionSettings.local
151+
}

bin/runner.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,11 @@ var argv = yargs
164164
describe: Constants.cliMessages.RUN.BUILD_NAME,
165165
type: "string",
166166
default: undefined
167+
},
168+
'disable-npm-warning': {
169+
default: false,
170+
description: Constants.cliMessages.COMMON.NO_NPM_WARNING,
171+
type: "boolean"
167172
}
168173
})
169174
.help('help')

test/unit/bin/commands/runs.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,7 @@ describe("runs", () => {
436436
zipUploadStub = sandbox.stub();
437437
createBuildStub = sandbox.stub();
438438
deleteZipStub = sandbox.stub();
439+
isUndefinedStub = sandbox.stub();
439440
});
440441

441442
afterEach(() => {
@@ -458,7 +459,8 @@ describe("runs", () => {
458459
setBuildName: setBuildNameStub,
459460
setUsageReportingFlag: setUsageReportingFlagStub,
460461
setParallels: setParallelsStub,
461-
getConfigPath: getConfigPathStub
462+
getConfigPath: getConfigPathStub,
463+
isUndefined: isUndefinedStub
462464
},
463465
"../helpers/capabilityHelper": {
464466
validate: capabilityValidatorStub,

0 commit comments

Comments
 (0)