browserstack-cypress-cli
Advanced tools
Comparing version 1.1.6 to 1.2.0
@@ -7,14 +7,16 @@ 'use strict'; | ||
Constants = require("../helpers/constants"), | ||
util = require("../helpers/util"); | ||
utils = require("../helpers/utils"); | ||
module.exports = function info(args) { | ||
return buildInfo(args) | ||
} | ||
function buildInfo(args) { | ||
let bsConfigPath = process.cwd() + args.cf; | ||
util.validateBstackJson(bsConfigPath).then(function (bsConfig) { | ||
util.setUsageReportingFlag(bsConfig, args.disableUsageReporting); | ||
return utils.validateBstackJson(bsConfigPath).then(function (bsConfig) { | ||
// accept the username from command line if provided | ||
utils.setUsername(bsConfig, args); | ||
// accept the access key from command line if provided | ||
utils.setAccessKey(bsConfig, args); | ||
utils.setUsageReportingFlag(bsConfig, args.disableUsageReporting); | ||
let buildId = args._[1]; | ||
@@ -24,3 +26,2 @@ | ||
url: config.buildUrl + buildId, | ||
method: "GET", | ||
auth: { | ||
@@ -31,7 +32,7 @@ user: bsConfig.auth.username, | ||
headers: { | ||
"User-Agent": util.getUserAgent(), | ||
"User-Agent": utils.getUserAgent(), | ||
}, | ||
}; | ||
request(options, function (err, resp, body) { | ||
request.get(options, function (err, resp, body) { | ||
let message = null; | ||
@@ -90,9 +91,9 @@ let messageType = null; | ||
} | ||
util.sendUsageReport(bsConfig, args, message, messageType, errorCode); | ||
utils.sendUsageReport(bsConfig, args, message, messageType, errorCode); | ||
}) | ||
}).catch(function (err) { | ||
logger.error(err); | ||
util.setUsageReportingFlag(null, args.disableUsageReporting); | ||
util.sendUsageReport(null, args, err.message, Constants.messageTypes.ERROR, util.getErrorCodeFromErr(err)); | ||
utils.setUsageReportingFlag(null, args.disableUsageReporting); | ||
utils.sendUsageReport(null, args, err.message, Constants.messageTypes.ERROR, utils.getErrorCodeFromErr(err)); | ||
}) | ||
} |
@@ -5,10 +5,5 @@ 'use strict'; | ||
logger = require("../helpers/logger").winstonLogger, | ||
util = require("../helpers/util"); | ||
utils = require("../helpers/utils"); | ||
module.exports = function init(args) { | ||
return createBrowserStackConfig(args) | ||
} | ||
function createBrowserStackConfig(args) { | ||
if (args.p) { | ||
@@ -28,3 +23,3 @@ var path_to_bsconf = args.p + "/browserstack.json"; | ||
logger.info(message); | ||
util.sendUsageReport(null, args, message, Constants.messageTypes.SUCCESS, null); | ||
utils.sendUsageReport(null, args, message, Constants.messageTypes.SUCCESS, null); | ||
} | ||
@@ -36,7 +31,7 @@ | ||
logger.error(message); | ||
util.sendUsageReport(null, args, message, Constants.messageTypes.ERROR, 'bstack_json_already_exists'); | ||
utils.sendUsageReport(null, args, message, Constants.messageTypes.ERROR, 'bstack_json_already_exists'); | ||
} else { | ||
fileHelpers.write(config, null, allDone); | ||
} | ||
}) | ||
}); | ||
} |
'use strict'; | ||
const fs = require('fs'); | ||
const archiver = require("../helpers/archiver"), | ||
@@ -11,38 +9,37 @@ zipUploader = require("../helpers/zipUpload"), | ||
Constants = require("../helpers/constants"), | ||
util = require("../helpers/util"); | ||
utils = require("../helpers/utils"), | ||
fileHelpers = require("../helpers/fileHelpers"); | ||
module.exports = function run(args) { | ||
return runCypress(args); | ||
} | ||
let bsConfigPath = process.cwd() + args.cf; | ||
function deleteZip() { | ||
fs.unlink(config.fileName, function (err) { | ||
if(err) { | ||
logger.info(Constants.userMessages.ZIP_DELETE_FAILED); | ||
} else { | ||
logger.info(Constants.userMessages.ZIP_DELETED); | ||
} | ||
}); | ||
} | ||
return utils.validateBstackJson(bsConfigPath).then(function (bsConfig) { | ||
utils.setUsageReportingFlag(bsConfig, args.disableUsageReporting); | ||
function runCypress(args) { | ||
let bsConfigPath = process.cwd() + args.cf; | ||
// accept the username from command line if provided | ||
utils.setUsername(bsConfig, args); | ||
util.validateBstackJson(bsConfigPath).then(function (bsConfig) { | ||
util.setUsageReportingFlag(bsConfig, args.disableUsageReporting); | ||
// accept the access key from command line if provided | ||
utils.setAccessKey(bsConfig, args); | ||
// Validate browserstack.json values | ||
capabilityHelper.validate(bsConfig).then(function (validated) { | ||
// accept the build name from command line if provided | ||
utils.setBuildName(bsConfig, args); | ||
// Validate browserstack.json values and parallels specified via arguments | ||
return capabilityHelper.validate(bsConfig, args).then(function (validated) { | ||
logger.info(validated); | ||
// accept the number of parallels | ||
utils.setParallels(bsConfig, args); | ||
// Archive the spec files | ||
archiver.archive(bsConfig.run_settings, config.fileName).then(function (data) { | ||
return archiver.archive(bsConfig.run_settings, config.fileName).then(function (data) { | ||
// Uploaded zip file | ||
zipUploader.zipUpload(bsConfig, config.fileName).then(function (zip) { | ||
return zipUploader.zipUpload(bsConfig, config.fileName).then(function (zip) { | ||
// Create build | ||
build.createBuild(bsConfig, zip).then(function (message) { | ||
return build.createBuild(bsConfig, zip).then(function (message) { | ||
logger.info(message); | ||
util.sendUsageReport(bsConfig, args, message, Constants.messageTypes.SUCCESS, null); | ||
utils.sendUsageReport(bsConfig, args, message, Constants.messageTypes.SUCCESS, null); | ||
return; | ||
@@ -52,11 +49,11 @@ }).catch(function (err) { | ||
logger.error(err); | ||
util.sendUsageReport(bsConfig, args, err, Constants.messageTypes.ERROR, 'build_failed'); | ||
utils.sendUsageReport(bsConfig, args, err, Constants.messageTypes.ERROR, 'build_failed'); | ||
}); | ||
}).catch(function (err) { | ||
// Zip Upload failed | ||
logger.error(err) | ||
logger.error(Constants.userMessages.ZIP_UPLOAD_FAILED) | ||
util.sendUsageReport(bsConfig, args, `${err}\n${Constants.userMessages.ZIP_UPLOAD_FAILED}`, Constants.messageTypes.ERROR, 'zip_upload_failed'); | ||
logger.error(err); | ||
logger.error(Constants.userMessages.ZIP_UPLOAD_FAILED); | ||
utils.sendUsageReport(bsConfig, args, `${err}\n${Constants.userMessages.ZIP_UPLOAD_FAILED}`, Constants.messageTypes.ERROR, 'zip_upload_failed'); | ||
}).finally(function () { | ||
deleteZip(); | ||
fileHelpers.deleteZip(); | ||
}); | ||
@@ -67,7 +64,7 @@ }).catch(function (err) { | ||
logger.error(Constants.userMessages.FAILED_TO_ZIP); | ||
util.sendUsageReport(bsConfig, args, `${err}\n${Constants.userMessages.FAILED_TO_ZIP}`, Constants.messageTypes.ERROR, 'zip_creation_failed'); | ||
utils.sendUsageReport(bsConfig, args, `${err}\n${Constants.userMessages.FAILED_TO_ZIP}`, Constants.messageTypes.ERROR, 'zip_creation_failed'); | ||
try { | ||
deleteZip(); | ||
fileHelpers.deleteZip(); | ||
} catch (err) { | ||
util.sendUsageReport(bsConfig, args, Constants.userMessages.ZIP_DELETE_FAILED, Constants.messageTypes.ERROR, 'zip_deletion_failed'); | ||
utils.sendUsageReport(bsConfig, args, Constants.userMessages.ZIP_DELETE_FAILED, Constants.messageTypes.ERROR, 'zip_deletion_failed'); | ||
} | ||
@@ -78,12 +75,17 @@ }); | ||
logger.error(err); | ||
logger.error(Constants.validationMessages.NOT_VALID); | ||
let error_code = util.getErrorCodeFromMsg(err); | ||
util.sendUsageReport(bsConfig, args, `${err}\n${Constants.validationMessages.NOT_VALID}`, Constants.messageTypes.ERROR, error_code); | ||
// display browserstack.json is not valid only if validation of browserstack.json field has failed, otherwise display just the error message | ||
// If parallels specified in arguments are invalid do not display browserstack.json is invalid message | ||
if (!(err === Constants.validationMessages.INVALID_PARALLELS_CONFIGURATION && !utils.isUndefined(args.parallels))) { | ||
logger.error(Constants.validationMessages.NOT_VALID); | ||
} | ||
let error_code = utils.getErrorCodeFromMsg(err); | ||
utils.sendUsageReport(bsConfig, args, `${err}\n${Constants.validationMessages.NOT_VALID}`, Constants.messageTypes.ERROR, error_code); | ||
}); | ||
}).catch(function (err) { | ||
logger.error(err); | ||
util.setUsageReportingFlag(null, args.disableUsageReporting); | ||
util.sendUsageReport(null, args, err.message, Constants.messageTypes.ERROR, util.getErrorCodeFromErr(err)); | ||
}) | ||
utils.setUsageReportingFlag(null, args.disableUsageReporting); | ||
utils.sendUsageReport(null, args, err.message, Constants.messageTypes.ERROR, utils.getErrorCodeFromErr(err)); | ||
}); | ||
} |
@@ -7,14 +7,16 @@ 'use strict'; | ||
Constants = require("../helpers/constants"), | ||
util = require("../helpers/util"); | ||
utils = require("../helpers/utils"); | ||
module.exports = function stop(args) { | ||
return buildStop(args) | ||
} | ||
function buildStop(args) { | ||
let bsConfigPath = process.cwd() + args.cf; | ||
util.validateBstackJson(bsConfigPath).then(function (bsConfig) { | ||
util.setUsageReportingFlag(bsConfig, args.disableUsageReporting); | ||
return utils.validateBstackJson(bsConfigPath).then(function (bsConfig) { | ||
// accept the username from command line if provided | ||
utils.setUsername(bsConfig, args); | ||
// accept the access key from command line if provided | ||
utils.setAccessKey(bsConfig, args); | ||
utils.setUsageReportingFlag(bsConfig, args.disableUsageReporting); | ||
let buildId = args._[1]; | ||
@@ -24,3 +26,2 @@ | ||
url: config.buildStopUrl + buildId, | ||
method: "POST", | ||
auth: { | ||
@@ -31,7 +32,7 @@ user: bsConfig.auth.username, | ||
headers: { | ||
"User-Agent": util.getUserAgent(), | ||
"User-Agent": utils.getUserAgent(), | ||
}, | ||
}; | ||
request(options, function (err, resp, body) { | ||
request.post(options, function (err, resp, body) { | ||
let message = null; | ||
@@ -86,9 +87,9 @@ let messageType = null; | ||
} | ||
util.sendUsageReport(bsConfig, args, message, messageType, errorCode); | ||
utils.sendUsageReport(bsConfig, args, message, messageType, errorCode); | ||
}) | ||
}).catch(function (err) { | ||
logger.error(err); | ||
util.setUsageReportingFlag(null, args.disableUsageReporting); | ||
util.sendUsageReport(null, args, err.message, Constants.messageTypes.ERROR, util.getErrorCodeFromErr(err)); | ||
utils.setUsageReportingFlag(null, args.disableUsageReporting); | ||
utils.sendUsageReport(null, args, err.message, Constants.messageTypes.ERROR, utils.getErrorCodeFromErr(err)); | ||
}) | ||
} |
@@ -39,4 +39,3 @@ 'use strict'; | ||
let allowedFileTypes = [ 'js', 'json', 'txt', 'ts' ] | ||
let allowedFileTypes = [ 'js', 'json', 'txt', 'ts' ]; | ||
allowedFileTypes.forEach(fileType => { | ||
@@ -43,0 +42,0 @@ archive.glob(`**/*.${fileType}`, { cwd: cypressFolderPath, matchBase: true, ignore: ['node_modules/**', 'package-lock.json', 'package.json', 'browserstack-package.json'] }); |
@@ -7,3 +7,3 @@ 'use strict'; | ||
Constants = require('../helpers/constants'), | ||
util =require('../helpers/util'); | ||
utils =require('../helpers/utils'); | ||
@@ -21,7 +21,7 @@ const createBuild = (bsConfig, zip) => { | ||
'Content-Type': 'application/json', | ||
"User-Agent": util.getUserAgent(), | ||
"User-Agent": utils.getUserAgent(), | ||
}, | ||
body: data | ||
} | ||
request.post(options, function (err, resp, body) { | ||
@@ -28,0 +28,0 @@ if (err) { |
const logger = require("./logger").winstonLogger, | ||
Constants = require("./constants"); | ||
Constants = require("./constants"), | ||
Utils = require("./utils"), | ||
fs = require('fs'), | ||
path = require('path'); | ||
const caps = (bsConfig, zip) => { | ||
return new Promise(function (resolve, reject) { | ||
let user = bsConfig.auth.username | ||
let password = bsConfig.auth.access_key | ||
let user = undefined; | ||
let password = undefined; | ||
if (bsConfig.auth) { | ||
user = bsConfig.auth.username; | ||
password = bsConfig.auth.access_key; | ||
} | ||
if (!user || !password) reject(Constants.validationMessages.INCORRECT_AUTH_PARAMS); | ||
@@ -15,9 +23,11 @@ | ||
let osBrowserArray = []; | ||
bsConfig.browsers.forEach(element => { | ||
osBrowser = element.os + "-" + element.browser | ||
element.versions.forEach(version => { | ||
osBrowserArray.push(osBrowser + version); | ||
if (bsConfig.browsers) { | ||
bsConfig.browsers.forEach((element) => { | ||
osBrowser = element.os + "-" + element.browser; | ||
element.versions.forEach((version) => { | ||
osBrowserArray.push(osBrowser + version); | ||
}); | ||
}); | ||
}); | ||
obj.devices = osBrowserArray | ||
} | ||
obj.devices = osBrowserArray; | ||
if (obj.devices.length == 0) reject(Constants.validationMessages.EMPTY_BROWSER_LIST); | ||
@@ -27,4 +37,7 @@ logger.info(`Browser list: ${osBrowserArray.toString()}`); | ||
// Test suite | ||
obj.test_suite = zip.zip_url.split("://")[1] | ||
if (!obj.test_suite || 0 === obj.test_suite.length) reject("Test suite is empty"); | ||
if (zip.zip_url && zip.zip_url.split("://")[1].length !== 0) { | ||
obj.test_suite = zip.zip_url.split("://")[1]; | ||
} else { | ||
reject("Test suite is empty"); | ||
} | ||
logger.info(`Test suite: bs://${obj.test_suite}`); | ||
@@ -34,3 +47,3 @@ | ||
obj.local = false; | ||
if (bsConfig.connection_settings.local === true) obj.local = true; | ||
if (bsConfig.connection_settings && bsConfig.connection_settings.local === true) obj.local = true; | ||
logger.info(`Local is set to: ${obj.local}`); | ||
@@ -47,17 +60,28 @@ | ||
// Project name | ||
obj.project = bsConfig.run_settings.project || bsConfig.run_settings.project_name; | ||
if (!obj.project) logger.log(`Project name is: ${obj.project}`); | ||
obj.project = "project-name"; | ||
// Build name | ||
obj.customBuildName = "build-name"; | ||
//callback url | ||
obj.callbackURL = null; | ||
//projectNotifyURL | ||
obj.projectNotifyURL = null; | ||
// Build name | ||
obj.customBuildName = bsConfig.run_settings.customBuildName || bsConfig.run_settings.build_name; | ||
if (bsConfig.run_settings) { | ||
obj.project = bsConfig.run_settings.project || bsConfig.run_settings.project_name; | ||
obj.customBuildName = bsConfig.run_settings.build_name || bsConfig.run_settings.customBuildName; | ||
obj.callbackURL = bsConfig.run_settings.callback_url; | ||
obj.projectNotifyURL = bsConfig.run_settings.project_notify_URL; | ||
obj.parallels = bsConfig.run_settings.parallels; | ||
} | ||
if (obj.project) logger.log(`Project name is: ${obj.project}`); | ||
if (obj.customBuildName) logger.log(`Build name is: ${obj.customBuildName}`); | ||
//callback url | ||
obj.callbackURL = bsConfig.run_settings.callback_url | ||
if (obj.callbackURL) logger.info(`callback url is : ${obj.callbackURL}`); | ||
//projectNotifyURL | ||
obj.projectNotifyURL = bsConfig.run_settings.project_notify_URL | ||
if (obj.projectNotifyURL) logger.info(`Project notify URL is: ${obj.projectNotifyURL}`); | ||
if (obj.parallels) logger.info(`Parallels limit specified: ${obj.parallels}`); | ||
var data = JSON.stringify(obj); | ||
@@ -68,3 +92,3 @@ resolve(data); | ||
const validate = (bsConfig) => { | ||
const validate = (bsConfig, args) => { | ||
return new Promise(function(resolve, reject){ | ||
@@ -79,4 +103,19 @@ if (!bsConfig) reject(Constants.validationMessages.EMPTY_BROWSERSTACK_JSON); | ||
if(!bsConfig.run_settings.cypress_proj_dir) reject(Constants.validationMessages.EMPTY_SPEC_FILES); | ||
if (!bsConfig.run_settings.cypress_proj_dir) reject(Constants.validationMessages.EMPTY_SPEC_FILES); | ||
// 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); | ||
// if parallels specified via arguments validate only arguments | ||
if (!Utils.isUndefined(args) && !Utils.isUndefined(args.parallels) && !Utils.isParallelValid(args.parallels)) reject(Constants.validationMessages.INVALID_PARALLELS_CONFIGURATION); | ||
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){ | ||
reject(Constants.validationMessages.INVALID_CYPRESS_JSON) | ||
} | ||
resolve(Constants.validationMessages.VALIDATED); | ||
@@ -83,0 +122,0 @@ }); |
@@ -27,2 +27,5 @@ const userMessages = { | ||
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" | ||
}; | ||
@@ -50,8 +53,12 @@ | ||
RUN: { | ||
PARALLEL_DESC: "The maximum number of parallels to use to run your test suite", | ||
INFO: "Run your tests on BrowserStack.", | ||
DESC: "Path to BrowserStack config", | ||
CONFIG_DEMAND: "config file is required" | ||
CONFIG_DEMAND: "config file is required", | ||
BUILD_NAME: "The build name you want to use to name your test runs" | ||
}, | ||
COMMON: { | ||
DISABLE_USAGE_REPORTING: "Disable usage reporting" | ||
DISABLE_USAGE_REPORTING: "Disable usage reporting", | ||
USERNAME: "Your BrowserStack username", | ||
ACCESS_KEY: "Your BrowserStack access key" | ||
} | ||
@@ -58,0 +65,0 @@ } |
'use strict'; | ||
const fs = require('fs-extra'), | ||
path = require('path'), | ||
mkdirp = require('mkdirp'); | ||
path = require('path'); | ||
const logger = require('./logger').winstonLogger; | ||
const logger = require("./logger").winstonLogger, | ||
Constants = require("../helpers/constants"), | ||
config = require("../helpers/config"); | ||
exports.isEmpty = function(path, cb) { | ||
fs.readdir(path, function(err, files) { | ||
if (err && 'ENOENT' != err.code) throw err; | ||
cb(!files || !files.length); | ||
}); | ||
} | ||
exports.isDirectory = function(path, cb) { | ||
fs.stat(path, function(err, stats) { | ||
if (err && 'ENOENT' != err.code) throw err; | ||
if (err) { | ||
return cb(false) | ||
} | ||
cb(stats.isDirectory()) | ||
}) | ||
} | ||
exports.isFile = function(path, cb) { | ||
fs.stat(path, function(err, stats) { | ||
if (err && 'ENOENT' != err.code) throw err; | ||
if (err) { | ||
return cb(false) | ||
} | ||
cb(stats.isFile()) | ||
}) | ||
} | ||
exports.mkdir = function(dir, cb) { | ||
mkdirp(dir, '0755', function(err) { | ||
if (err) throw err; | ||
logger.info("Creating directory: ./" + path.relative(process.cwd(), dir)); | ||
cb && cb() | ||
}) | ||
} | ||
exports.write = function(f, message, cb) { | ||
@@ -51,3 +17,3 @@ message = message || 'Creating'; | ||
exports.fileExists = function(filePath, cb) { | ||
exports.fileExists = function (filePath, cb) { | ||
fs.access(filePath, fs.F_OK, (err) => { | ||
@@ -58,5 +24,16 @@ let exists = true; | ||
} | ||
cb && cb(exists); | ||
}); | ||
}; | ||
cb && cb(exists) | ||
}) | ||
exports.deleteZip = () => { | ||
return fs.unlink(config.fileName, function (err) { | ||
if (err) { | ||
logger.info(Constants.userMessages.ZIP_DELETE_FAILED); | ||
return 1; | ||
} else { | ||
logger.info(Constants.userMessages.ZIP_DELETED); | ||
return 0; | ||
} | ||
}); | ||
} |
@@ -14,2 +14,3 @@ const winston = require('winston'), | ||
new winston.transports.Console({ | ||
name: 'console.info', | ||
colorize: true, | ||
@@ -16,0 +17,0 @@ timestamp: function () { |
@@ -7,3 +7,3 @@ 'use strict'; | ||
Constants = require("./constants"), | ||
util = require("./util"); | ||
utils = require("./utils"); | ||
@@ -24,3 +24,3 @@ const uploadCypressZip = (bsConfig, filePath) => { | ||
headers: { | ||
"User-Agent": util.getUserAgent(), | ||
"User-Agent": utils.getUserAgent(), | ||
} | ||
@@ -27,0 +27,0 @@ } |
@@ -65,2 +65,14 @@ #!/usr/bin/env node | ||
}, | ||
'u': { | ||
alias: 'username', | ||
describe: Constants.cliMessages.COMMON.USERNAME, | ||
type: "string", | ||
default: undefined | ||
}, | ||
'k': { | ||
alias: 'key', | ||
describe: Constants.cliMessages.COMMON.ACCESS_KEY, | ||
type: "string", | ||
default: undefined | ||
}, | ||
}) | ||
@@ -94,2 +106,14 @@ .help('help') | ||
}, | ||
'u': { | ||
alias: 'username', | ||
describe: Constants.cliMessages.COMMON.USERNAME, | ||
type: "string", | ||
default: undefined | ||
}, | ||
'k': { | ||
alias: 'key', | ||
describe: Constants.cliMessages.COMMON.ACCESS_KEY, | ||
type: "string", | ||
default: undefined | ||
}, | ||
}) | ||
@@ -106,3 +130,3 @@ .help('help') | ||
argv = yargs | ||
.usage('usage: $0 build') | ||
.usage('usage: $0 run <options>') | ||
.options({ | ||
@@ -123,2 +147,26 @@ 'cf': { | ||
}, | ||
'p': { | ||
alias: 'parallels', | ||
describe: Constants.cliMessages.RUN.PARALLEL_DESC, | ||
type: "number", | ||
default: undefined | ||
}, | ||
'u': { | ||
alias: 'username', | ||
describe: Constants.cliMessages.COMMON.USERNAME, | ||
type: "string", | ||
default: undefined | ||
}, | ||
'k': { | ||
alias: 'key', | ||
describe: Constants.cliMessages.COMMON.ACCESS_KEY, | ||
type: "string", | ||
default: undefined | ||
}, | ||
'b': { | ||
alias: 'build-name', | ||
describe: Constants.cliMessages.RUN.BUILD_NAME, | ||
type: "string", | ||
default: undefined | ||
} | ||
}) | ||
@@ -125,0 +173,0 @@ .help('help') |
module.exports = function () { | ||
var config = { | ||
"auth": { | ||
"username": "<username>", | ||
"access_key": "<access-key>" | ||
"username": "<Your BrowserStack username>", | ||
"access_key": "<Your BrowserStack access key>" | ||
}, | ||
@@ -15,5 +15,6 @@ "browsers": [ | ||
"run_settings": { | ||
"cypress_proj_dir" : "/path/to/cypress.json", | ||
"cypress_proj_dir" : "/path/to/directory-that-contains-<cypress.json>-file", | ||
"project_name": "project-name", | ||
"build_name": "build-name", | ||
"parallels": "Here goes the number of parallels you want to run", | ||
"npm_dependencies": { | ||
@@ -20,0 +21,0 @@ } |
{ | ||
"name": "browserstack-cypress-cli", | ||
"version": "1.1.6", | ||
"version": "1.2.0", | ||
"description": "BrowserStack Cypress CLI for Cypress integration with BrowserStack's remote devices.", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
"test": "nyc mocha 'test/**/*.js' --recursive --timeout 60000 --exit" | ||
}, | ||
@@ -30,3 +30,12 @@ "author": "BrowserStack", | ||
"url": "https://github.com/browserstack/browserstack-cypress-cli/issues" | ||
}, | ||
"devDependencies": { | ||
"chai": "^4.2.0", | ||
"chai-as-promised": "^7.1.1", | ||
"mocha": "^7.1.2", | ||
"nyc": "^15.0.1", | ||
"proxyquire": "^2.1.3", | ||
"rewire": "^5.0.0", | ||
"sinon": "^9.0.2" | ||
} | ||
} |
418
README.md
@@ -5,2 +5,6 @@ # BrowserStack Cypress CLI | ||
> **Note**: Running Cypress tests on BrowserStack is now in public beta. Learn more [here](https://browserstack.com/cypress) | ||
> | ||
> If you are looking for a getting started guide, and a more up-to date documentation, check out the [BrowserStack Cypress documentation](https://browserstack.com/docs/automate/cypress) | ||
The `browserstack-cypress-cli` is BrowserStack's command-line interface (CLI) which | ||
@@ -10,15 +14,4 @@ allows you to run your Cypress tests on BrowserStack. | ||
- [Quick Start](#quick-start) | ||
- [Configuration Options](#configuration-options) | ||
- [Authentication](#authentication) | ||
- [Specify Browsers](#specify-browsers) | ||
- [Configure Test Runs](#configure-test-runs) | ||
- [Configure Connection Settings](#configure-connection-settings) | ||
- [Disable Usage Reporting](#disable-usage-reporting) | ||
- [Deprecated Options](#deprecated-options) | ||
- [CLI Arguments & Flags](#cli-arguments--flags) | ||
- [Run the Tests](#run-the-tests) | ||
- [Get the Build Information](#get-the-build-information) | ||
- [Stop a Running Build](#stop-a-running-build) | ||
- [Disable CLI Usage Reporting](#disable-cli-usage-reporting) | ||
- [Limitations](#limitations) | ||
- [Documentation](#documentation) | ||
- [Getting Help](#getting-help) | ||
- [License](#license) | ||
@@ -28,4 +21,8 @@ | ||
First, install the CLI: | ||
Running your first Cypress test suite on BrowserStack is super easy - just install our CLI, configure the test run settings and start testing. Here’s a quick start guide to help you get started. | ||
### Step 1: Install the CLI | ||
First, install the BrowserStack - Cypress CLI via `npm`: | ||
```bash | ||
@@ -36,9 +33,5 @@ # Install the BrowserStack Cypress CLI | ||
Note that we run tests that are written using Cypress 4.0 and above. Update to | ||
a newer version if you are using an older version of Cypress and update your | ||
tests if required. | ||
### Step 2: Configure | ||
Next, set up your BrowserStack credentials and configure the browsers that you | ||
want to run your tests on. Use the `init` command to generate a sample | ||
`browserstack.json` file, or alternatively create one from scratch. | ||
Next, set up your BrowserStack credentials and configure the browsers that you want to run your tests on. Use the `init` command to generate a sample `browserstack.json` file, or alternatively create one from scratch. | ||
@@ -50,202 +43,10 @@ ```bash | ||
Fill in the `auth`, `browsers`, `run_settings` values to be able to run your | ||
tests. Refer to the [configuration options](#configuration-options) to learn | ||
more about all the options you can use in `browserstack.json` and the possible | ||
values. | ||
Fill in the `auth`, `browsers`, `run_settings` values in the `browserstack.json` file to be able to run your tests. Refer to the [configuration options](https://browserstack.com/docs/automate/cypress#configure-test-run-settings) to learn more about all the options you can use in `browserstack.json` and the possible values that you can mention. | ||
Make sure you specify the npm packages that your tests need to run using the | ||
`npm_dependencies` option in `run_settings`. | ||
Make sure you also specify the `npm` packages that your tests need to run using the `npm_dependencies` option in `run_settings`. | ||
Then, run your tests on BrowserStack: | ||
### Step 3: Run your tests | ||
```bash | ||
$ browserstack-cypress run | ||
``` | ||
After you specify the required run settings, you can run your tests on BrowserStack: | ||
You can access the test results on the [BrowserStack Automate dashboard](https://automate.browserstack.com/). | ||
## Configuration Options | ||
The `init` command will create a sample `browserstack.json` file. This file can | ||
be used to configure your test runs on BrowserStack. Below is the sample file | ||
that is generated for your reference. | ||
You can also specify `--path <path-to-folder-where-you-need-init-to-run>` flag | ||
along with the `init` command to generate `browserstack.json` file in the | ||
specified folder. | ||
```json | ||
{ | ||
"auth": { | ||
"username": "<your-browserstack-username>", | ||
"access_key": "<your-browserstack-access-key>" | ||
}, | ||
"browsers": [ | ||
{ | ||
"browser": "chrome", | ||
"os": "Windows 10", | ||
"versions": ["79","78"] | ||
} | ||
], | ||
"run_settings": { | ||
"cypress_proj_dir": "/path/to/directory-that-contains-<cypress.json>-file", | ||
"project_name": "my first project", | ||
"build_name": "build 1", | ||
"npm_dependencies": { | ||
"npm-package-you-need-to-run-tests-1": "^1.2.1", | ||
"npm-package-you-need-to-run-tests-2": "^7.1.6-beta.13", | ||
} | ||
}, | ||
"connection_settings": { | ||
"local": false, | ||
"local_identifier": null | ||
}, | ||
"disable_usage_reporting": "false" | ||
} | ||
``` | ||
Here are all the options that you can provide in the `browserstack.json`: | ||
### Authentication | ||
You can use the `auth` option to specify your username and access keys. You | ||
can find them in your [Automate dashboard](https://automate.browserstack.com/) | ||
| Option | Description | Possible values | | ||
| ------------ | ----------------------------- | --------------- | | ||
| `username` | Your BrowserStack username. | - | | ||
| `access_key` | Your BrowserStack access key. | - | | ||
Example: | ||
```json | ||
{ | ||
"auth": { | ||
"username": "<your-browserstack-username>", | ||
"access_key": "<your-browserstack-access-key>" | ||
} | ||
} | ||
``` | ||
### Specify Browsers | ||
You can use the `browsers` option to specify the list of OS, browser and browser | ||
versions. Each browser combination should contain the following details: | ||
| Option | Description | Possible values | | ||
| ---------- | ---------------------------------------------- | --------------------------------------------------------------------- | | ||
| `os` | Operating system you want to run the tests on. | `Windows 10` | | ||
| `browser` | Browser you want to run the tests on. | `chrome`, `firefox` and `edge` | | ||
| `versions` | A list of supported browser versions. | Chrome: `66` to `81` <br/>Firefox: `60` to `75`<br/>Edge: `80` & `81` | | ||
Example: | ||
```json | ||
{ | ||
"browsers": [{ | ||
"os": "Windows 10", | ||
"browser": "chrome", | ||
"versions": ["79", "78"] | ||
}, | ||
{ | ||
"os": "Windows 10", | ||
"browser": "firefox", | ||
"versions": ["69", "66"] | ||
} | ||
] | ||
} | ||
``` | ||
### Configure Test Runs | ||
You can use `run_settings` option to specify the settings to run your tests on | ||
BrowserStack. | ||
| Option | Description | Possible values | | ||
| ------------------ | ---------------------------------------------------------------------------------------------------------------- | --------------- | | ||
| `cypress_proj_dir` | Path to the folder which contains `cypress.json` file. | - | | ||
| `project_name` | Name of your project. You'll be able to search & filter your tests on the dashboard using this. | - | | ||
| `build_name` | Name of your build / CI run. You'll be able to search & filter your tests on the dashboard using this. username. | - | | ||
| `npm_dependencies` | A list of NPM packages that are required to run your Cypress tests along with their version numbers. | - | | ||
Example: | ||
```json | ||
{ | ||
"run_settings": { | ||
"cypress_proj_dir": "/path/to/directory-that-contains-<cypress.json>-file", | ||
"project_name": "my first project", | ||
"build_name": "build 1", | ||
"npm_dependencies": { | ||
"npm-package-you-need-to-run-tests-1": "^1.2.1", | ||
"npm-package-you-need-to-run-tests-2": "^7.1.6-beta.13", | ||
} | ||
} | ||
} | ||
``` | ||
### Configure Connection Settings | ||
You can use the `connection_settings` option to specify the Local connection | ||
settings. This helps you in testing websites that cannot be accessed on the | ||
public network. You can download the Local Testing binary and establish a local | ||
connection first before you run the tests (you can learn how to do so | ||
[here](https://www.browserstack.com/local-testing/automate#command-line)) | ||
| Option | Description | Possible values | | ||
| ------------------ | ---------------------------------------------------------------------- | --------------- | | ||
| `local` | Helps in testing private web applications. | - | | ||
| `local_identifier` | The BrowserStack Local tunnel that should be used to resolve requests. | - | | ||
Note that the `local_identifier` is applicable only when you start a Local | ||
binary with a local identifier. Your tests might fail if you use an invalid | ||
local identifier. This option will be ignored if `local` option is set to | ||
`false`. | ||
Example: | ||
```json | ||
{ | ||
"connection_settings": { | ||
"local": false, | ||
"local_identifier": null | ||
} | ||
} | ||
``` | ||
### Disable Usage Reporting | ||
The CLI collects anonymized usage data including the command-line arguments | ||
used, system details and errors that you get so that we can improve the way | ||
you run your Cypress tests on BrowserStack. Usage reporting is enabled by | ||
default - you can disable usage reporting by using the `disable_usage_reporting` | ||
option as follows: | ||
Example: | ||
```json | ||
{ | ||
"disable_usage_reporting": "false" | ||
} | ||
``` | ||
### Deprecated Options | ||
The following options are deprecated in favour of the new improved options to | ||
make your testing better, flexible and have a consistent way of specifying | ||
options. | ||
| Deprecated option | New favoured option | Remarks | | ||
| ----------------- | ------------------- | ----------------------------- | | ||
| `specs` | `cypress_proj_dir` | Used in `run_settings` | | ||
| `project` | `project_name` | Used in `run_settings` | | ||
| `customBuildName` | `build_name` | Used in `run_settings` | | ||
| `localIdentifier` | `local_identifier` | Used in `connection_settings` | | ||
## CLI Arguments & Flags | ||
### Run the Tests | ||
You can start running your test build using the following command. | ||
```bash | ||
@@ -255,182 +56,21 @@ $ browserstack-cypress run | ||
By default, the CLI uses the `browserstack.json` in the directory where the | ||
`run` command is issued. If you need to use a different config file, or are | ||
running from a different directory, you can use the `--cf` or the `--config-file` | ||
option while using `run`. For example, | ||
After the tests are successfully submitted, you can access the test results on the [BrowserStack Automate dashboard](https://automate.browserstack.com/dashboard/v2) | ||
```bash | ||
$ browserstack-cypress --cf <path-to-browserstack.json> run | ||
To learn more about the different options the CLI supports - like running tests in parallel, running tests on `localhost` URLs etc., refer to the [BrowserStack Cypress documentation](https://browserstack.com/docs/automate/cypress) | ||
# Or | ||
$ browserstack-cypress --config-file <path-to-browserstack.json> run | ||
``` | ||
## Documentation | ||
Sample output : | ||
Here are a few important links to get you started and help you successfully integrate the CLI into your CI/CD pipelines. | ||
```bash | ||
[2/20/2020, 2:58:31 PM] Reading browserstack.json from /browserstack.json | ||
[2/20/2020, 2:58:31 PM] browserstack.json file is validated | ||
[2/20/2020, 2:58:31 PM] Adding tests/*.js to zip | ||
[2/20/2020, 2:58:34 PM] Zip uploaded with url: bs://15f90b540b8cbc47929782f35bb7db20fe1c4709 | ||
[2/20/2020, 2:58:34 PM] File deleted successfully | ||
[2/20/2020, 2:58:34 PM] Browser list: OS X Catalina-chrome69,OS X Catalina-chrome66 | ||
[2/20/2020, 2:58:34 PM] Test suite: bs://15f90b540b8cbc47929782f35bb7db20fe1c4709 | ||
[2/20/2020, 2:58:34 PM] Local is set to: false | ||
[2/20/2020, 2:58:34 PM] Build name is: cypress build | ||
[2/20/2020, 2:58:34 PM] Success | ||
[2/20/2020, 2:58:36 PM] Build created with build id: 06f28ce423d10314b32e98bb6f68e10b0d02a49a | ||
[2/20/2020, 2:58:36 PM] File deleted successfully. | ||
``` | ||
- [List of supported browsers & OS](https://browserstack.com/list-of-browsers-and-platforms?product=cypress_testing) | ||
- [Tutorial with the Kitchen Sink sample app](https://browserstack.com/docs/automate/cypress#sample-tutorial) | ||
- [Run Tests in Localhost / Dev / Staging Environments](https://browserstack.com/docs/automate/cypress#run-tests-in-dev-environments) | ||
- [Run Tests in Parallel](https://browserstack.com/docs/automate/cypress#run-tests-in-parallel) | ||
- [Run Tests in CI/CD](https://browserstack.com/docs/automate/cypress#run-tests-in-cicd) | ||
- [CLI Reference](https://browserstack.com/docs/automate/cypress#cli-reference) | ||
### Get the Build Information | ||
## Getting Help | ||
In case you want to get information on the build you can use the following | ||
command | ||
If you need any help, want to share feedback or report issues while running the tests, reach out to us on support@browserstack.com. | ||
```bash | ||
$ browserstack-cypress build-info <buildId> | ||
``` | ||
By default, the CLI uses the `browserstack.json` in the directory where the | ||
`build-info` command is issued. If you need to use a different config file, or | ||
are running the command from a different directory, you can use the `--cf` or | ||
the `--config-file` option while using `build-info`. For example, | ||
```bash | ||
$ browserstack-cypress --cf <path-to-browserstack.json> build-info <buildId> | ||
# Or | ||
$ browserstack-cypress --config-file <path-to-browserstack.json> build-info <buildId> | ||
``` | ||
Example | ||
```bash | ||
$ browserstack-cypress build-info 06f28ce423d10314b32e98bb6f68e10b0d02a49a | ||
``` | ||
Sample output: | ||
```bash | ||
[2/20/2020, 3:01:52 PM] Getting information for buildId 06f28ce423d10314b32e98bb6f68e10b0d02a49a | ||
[2/20/2020, 3:01:52 PM] Reading browserstack.json from /browserstack.json | ||
[2/20/2020, 3:01:54 PM] Build info for build id: | ||
{ | ||
"build_id": "06f28ce423d10314b32e98bb6f68e10b0d02a49a", | ||
"framework": "cypress", | ||
"status": "done", | ||
"input_capabilities": { | ||
"devices": [ | ||
"OS X Catalina-chrome69", | ||
"OS X Catalina-chrome66" | ||
], | ||
"testSuite": "15f90b540b8cbc47929782f35bb7db20fe1c4709", | ||
"customBuildName": "cypress build", | ||
"local": false, | ||
"localIdentifier": null, | ||
"callbackURL": null, | ||
"projectNotifyURL": null, | ||
"project": "test" | ||
}, | ||
"start_time": "2020-02-20 09:28:35 UTC", | ||
"device_statuses": { | ||
"success": { | ||
"OS X Catalina-chrome69": "Success", | ||
"OS X Catalina-chrome66": "Success" | ||
}, | ||
"error": {} | ||
}, | ||
"test_suite_details": { | ||
"url": "bs://15f90b540b8cbc47929782f35bb7db20fe1c4709", | ||
"name": "tests.zip", | ||
"size": 354 | ||
}, | ||
"duration": "33 seconds", | ||
"devices": { | ||
"OS X Catalina-chrome69": { | ||
"session_id": "3b4038cbbc55d34c1b33c930f3417c7c534c25dd", | ||
"status": "done", | ||
"test_status": { | ||
"failed": 0, | ||
"success": 3, | ||
"queued": 0, | ||
"ignored": 0 | ||
} | ||
}, | ||
"OS X Catalina-chrome66": { | ||
"session_id": "fbda8eb5a9eeb7823a9ef7be1a42213c568197e8", | ||
"status": "done", | ||
"test_status": { | ||
"failed": 0, | ||
"success": 3, | ||
"queued": 0, | ||
"ignored": 0 | ||
} | ||
} | ||
} | ||
} | ||
``` | ||
**Note:** Each browser version represents a session. It is advised to validate | ||
your account's parallel limit before running multiple versions. | ||
### Stop a Running Build | ||
In case you want to stop a running build, you can use the following command | ||
```bash | ||
$ browserstack-cypress build-stop <buildId> | ||
``` | ||
By default, the CLI uses the `browserstack.json` in the directory where the | ||
`build-stop` command is issued. If you need to use a different config file, or | ||
are running the command from a different directory, you can use the `--cf` or | ||
the `--config-file` option while using `build-stop`. For example, | ||
```bash | ||
$ browserstack-cypress --cf <path-to-browserstack.json> build-stop <buildId> | ||
# Or | ||
$ browserstack-cypress --config-file <path-to-browserstack.json> build-stop <buildId> | ||
``` | ||
Example | ||
```bash | ||
$ browserstack-cypress build-stop 06f28ce423d10314b32e98bb6f68e10b0d02a49a | ||
``` | ||
Sample output: | ||
```bash | ||
[3/24/2020, 2:31:11 PM] Stopping build with given buildId 06f28ce423d10314b32e98bb6f68e10b0d02a49a | ||
[3/24/2020, 2:31:12 PM] Reading config from /browserstack.json | ||
[3/24/2020, 2:31:14 PM] { | ||
"message": "stopped 1 sessions", | ||
"stopped_session_count": 1 | ||
} | ||
``` | ||
### Disable CLI Usage Reporting | ||
The CLI collects anonymized usage data including the command-line arguments | ||
used, system details and errors that you get so that we can improve the way | ||
you run your Cypress tests on BrowserStack. Usage reporting is enabled by | ||
default - you can disable usage reporting by using the | ||
`--disable-usage-reporting` flag. You can also do this by setting the | ||
`disable_usage_reporting` option to `"true"` in `browserstack.json`. | ||
```bash | ||
$ browserstack-cypress --disable-usage-reporting <your-commands> | ||
``` | ||
## Limitations | ||
- `exec` and `task` are not allowed. | ||
- While using local, please make sure to create `/etc/hosts` entry pointing to | ||
some URL, and use that URL in the tests. The `localhost` URI doesn't work at | ||
the moment. You can use `http://bs-local.com` instead, to replace `localhost` | ||
- Installing npm packages using `npm_dependencies` is not supported for tests | ||
running on macOS. | ||
## License | ||
@@ -437,0 +77,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 12 instances in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
Found 1 instance in 1 package
144087
34
3838
0
7
74
55
3