Skip to content

Commit

Permalink
Merge branch 'master' of github.com:browserstack/browserstack-cypress…
Browse files Browse the repository at this point in the history
…-cli into CYP_372_ENV_VAR
  • Loading branch information
karanshah-browserstack committed Sep 2, 2020
2 parents e133c53 + 22c892e commit e2a7ddd
Show file tree
Hide file tree
Showing 9 changed files with 239 additions and 27 deletions.
6 changes: 6 additions & 0 deletions bin/commands/runs.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ 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)) {
logger.warn(Constants.userMessages.NO_PARALLELS);
}

if(!args.disableNpmWarning && bsConfig.run_settings.npm_dependencies && Object.keys(bsConfig.run_settings.npm_dependencies).length <= 0) logger.warn(Constants.userMessages.NO_NPM_DEPENDENCIES);

logger.info(message);
logger.info(dashboardLink);
utils.sendUsageReport(bsConfig, args, `${message}\n${dashboardLink}`, Constants.messageTypes.SUCCESS, null);
Expand Down
4 changes: 2 additions & 2 deletions bin/helpers/archiver.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ const archiveSpecs = (runSettings, filePath) => {

archive.pipe(output);

let allowedFileTypes = [ 'js', 'json', 'txt', 'ts', 'feature', 'features' ];
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/**', 'package-lock.json', 'package.json', 'browserstack-package.json'] });
archive.glob(`**/*.${fileType}`, { cwd: cypressFolderPath, matchBase: true, ignore: ['node_modules/**', 'package-lock.json', 'package.json', 'browserstack-package.json', 'tests.zip'] });
});

let packageJSON = {};
Expand Down
25 changes: 17 additions & 8 deletions bin/helpers/capabilityHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ const caps = (bsConfig, zip) => {

// Local Identifier
obj.localIdentifier = null;
if (obj.local === true && (bsConfig.connection_settings.localIdentifier || bsConfig.connection_settings.local_identifier))
{
if (obj.local === true && (bsConfig.connection_settings.localIdentifier || bsConfig.connection_settings.local_identifier)) {
obj.localIdentifier = bsConfig.connection_settings.localIdentifier || bsConfig.connection_settings.local_identifier;
logger.log(`Local Identifier is set to: ${obj.localIdentifier}`);
}
Expand All @@ -70,6 +69,8 @@ const caps = (bsConfig, zip) => {
obj.parallels = bsConfig.run_settings.parallels;
}

if(obj.parallels === Constants.constants.DEFAULT_PARALLEL_MESSAGE) obj.parallels = undefined

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

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

const validate = (bsConfig, args) => {
return new Promise(function(resolve, reject){
return new Promise(function (resolve, reject) {
if (!bsConfig) reject(Constants.validationMessages.EMPTY_BROWSERSTACK_JSON);

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

if( bsConfig.auth.username == "<Your BrowserStack username>" || bsConfig.auth.access_key == "<Your BrowserStack access key>" ) reject(Constants.validationMessages.INVALID_DEFAULT_AUTH_PARAMS);

if (!bsConfig.browsers || bsConfig.browsers.length === 0) reject(Constants.validationMessages.EMPTY_BROWSER_LIST);

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

if (!bsConfig.run_settings.cypress_proj_dir) reject(Constants.validationMessages.EMPTY_SPEC_FILES);
if (!bsConfig.run_settings.cypress_proj_dir) reject(Constants.validationMessages.EMPTY_CYPRESS_PROJ_DIR);

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

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

try{
let cypressJson = fs.readFileSync(path.join(bsConfig.run_settings.cypress_proj_dir, 'cypress.json'))
JSON.parse(cypressJson)
}catch(error){
try {
let cypressJson = fs.readFileSync(path.join(bsConfig.run_settings.cypress_proj_dir, 'cypress.json'));
cypressJson = JSON.parse(cypressJson);
// Cypress Json Base Url & Local true check
if (!Utils.isUndefined(cypressJson.baseUrl) && cypressJson.baseUrl.includes("localhost") && !Utils.getLocalFlag(bsConfig.connection_settings)) reject(Constants.validationMessages.LOCAL_NOT_SET);

// Detect if the user is not using the right directory structure, and throw an error
if (!Utils.isUndefined(cypressJson.integrationFolder) && !Utils.isCypressProjDirValid(bsConfig.run_settings.cypress_proj_dir,cypressJson.integrationFolder)) reject(Constants.validationMessages.INCORRECT_DIRECTORY_STRUCTURE);

} catch (error) {
reject(Constants.validationMessages.INVALID_CYPRESS_JSON)
}

Expand Down
19 changes: 15 additions & 4 deletions bin/helpers/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ const userMessages = {
ZIP_DELETED: "Zip file deleted successfully.",
API_DEPRECATED: "This version of API is deprecated, please use latest version of API.",
FAILED_TO_ZIP: "Failed to zip files.",
VISIT_DASHBOARD: "Visit the Automate dashboard for test reporting:"
VISIT_DASHBOARD: "Visit the Automate dashboard for test reporting:",
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",
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."
};

const validationMessages = {
Expand All @@ -21,14 +23,17 @@ const validationMessages = {
EMPTY_TEST_SUITE: "Test suite is empty",
EMPTY_BROWSERSTACK_JSON: "Empty browserstack.json",
EMPTY_RUN_SETTINGS: "Empty run settings",
EMPTY_SPEC_FILES: "No spec files specified in run_settings",
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.",
VALIDATED: "browserstack.json file is validated",
NOT_VALID: "browerstack.json is not valid",
NOT_VALID_JSON: "browerstack.json is not a valid json",
INVALID_EXTENSION: "Invalid files, please remove these files and try again.",
INVALID_PARALLELS_CONFIGURATION: "Invalid value specified for parallels to use. Maximum parallels to use should be a number greater than 0.",
CYPRESS_JSON_NOT_FOUND: "cypress.json file is not found at cypress_proj_dir path ",
INVALID_CYPRESS_JSON: "cypress.json is not a valid json"
INVALID_CYPRESS_JSON: "cypress.json is not a valid json",
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",
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",
INCORRECT_DIRECTORY_STRUCTURE: "No tests to run. Note that your Cypress tests should be in the same directory where the cypress.json exists."
};

const cliMessages = {
Expand Down Expand Up @@ -60,7 +65,8 @@ const cliMessages = {
COMMON: {
DISABLE_USAGE_REPORTING: "Disable usage reporting",
USERNAME: "Your BrowserStack username",
ACCESS_KEY: "Your BrowserStack access key"
ACCESS_KEY: "Your BrowserStack access key",
NO_NPM_WARNING: "No NPM warning if npm_dependencies is empty"
}
}

Expand All @@ -73,9 +79,14 @@ const messageTypes = {
NULL: null
}

const constants = {
DEFAULT_PARALLEL_MESSAGE: "Here goes the number of parallels you want to run"
}

module.exports = Object.freeze({
userMessages,
cliMessages,
validationMessages,
messageTypes,
constants
});
37 changes: 33 additions & 4 deletions bin/helpers/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ exports.validateBstackJson = (bsConfigPath) => {
resolve(bsConfig);
}
catch (e) {
reject(e);
reject("Couldn't find the browserstack.json file at \""+ bsConfigPath +"\". Please use --config-file <path to browserstack.json>.");
}
});
}
Expand All @@ -35,9 +35,24 @@ exports.getErrorCodeFromMsg = (errMsg) => {
case Constants.validationMessages.EMPTY_RUN_SETTINGS:
errorCode = "bstack_json_invalid_no_run_settings";
break;
case Constants.validationMessages.EMPTY_SPEC_FILES:
errorCode = "bstack_json_invalid_values";
case Constants.validationMessages.EMPTY_CYPRESS_PROJ_DIR:
errorCode = "bstack_json_invalid_no_cypress_proj_dir";
break;
case Constants.validationMessages.INVALID_DEFAULT_AUTH_PARAMS:
errorCode = "bstack_json_default_auth_keys";
break;
case Constants.validationMessages.INVALID_PARALLELS_CONFIGURATION:
errorCode = "invalid_parallels_specified";
break;
case Constants.validationMessages.LOCAL_NOT_SET:
errorCode = "cypress_json_base_url_no_local";
break;
case Constants.validationMessages.INCORRECT_DIRECTORY_STRUCTURE:
errorCode = "invalid_directory_structure";
break;
}
if(errMsg.includes("Please use --config-file <path to browserstack.json>.")){
errorCode = "bstack_json_path_invalid";
}
return errorCode;
}
Expand Down Expand Up @@ -101,7 +116,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);
return this.isUndefined(value) || !(isNaN(value) || this.isFloat(value) || parseInt(value, 10) === 0 || parseInt(value, 10) < -1 ) || value === Constants.constants.DEFAULT_PARALLEL_MESSAGE;
}

exports.getUserAgent = () => {
Expand Down Expand Up @@ -136,3 +151,17 @@ exports.deleteResults = () => {
fs.unlink("log/build_results.txt", function (err){
});
}

exports.isCypressProjDirValid = (cypressDir, cypressProjDir) => {
// Getting absolute path
cypressDir = path.resolve(cypressDir);
cypressProjDir = path.resolve(cypressProjDir);
if(cypressProjDir === cypressDir) return true;
let parentTokens = cypressDir.split('/').filter(i => i.length);
let childTokens = cypressProjDir.split('/').filter(i => i.length);
return parentTokens.every((t, i) => childTokens[i] === t);
}

exports.getLocalFlag = (connectionSettings) => {
return !this.isUndefined(connectionSettings) && !this.isUndefined(connectionSettings.local) && connectionSettings.local
}
5 changes: 5 additions & 0 deletions bin/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,11 @@ var argv = yargs
describe: Constants.cliMessages.RUN.BUILD_NAME,
type: "string",
default: undefined
},
'disable-npm-warning': {
default: false,
description: Constants.cliMessages.COMMON.NO_NPM_WARNING,
type: "boolean"
}
})
.help('help')
Expand Down
4 changes: 3 additions & 1 deletion test/unit/bin/commands/runs.js
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,7 @@ describe("runs", () => {
deleteZipStub = sandbox.stub();
exportResultsStub = sandbox.stub();
deleteResultsStub = sandbox.stub();
isUndefinedStub = sandbox.stub();
});

afterEach(() => {
Expand All @@ -476,7 +477,8 @@ describe("runs", () => {
setParallels: setParallelsStub,
getConfigPath: getConfigPathStub,
exportResults: exportResultsStub,
deleteResults: deleteResultsStub
deleteResults: deleteResultsStub,
isUndefined: isUndefinedStub
},
"../helpers/capabilityHelper": {
validate: capabilityValidatorStub,
Expand Down
Loading

0 comments on commit e2a7ddd

Please sign in to comment.