Skip to content

Commit 819f147

Browse files
committed
Merge branch 'master' of github.com:roshan04/browserstack-cypress-cli
2 parents 64456e8 + 699ca7c commit 819f147

22 files changed

+594
-49
lines changed

bin/commands/runs.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,12 @@ const archiver = require("../helpers/archiver"),
2222
const { getStackTraceUrl } = require('../helpers/sync/syncSpecsLogs');
2323

2424
module.exports = function run(args, rawArgs) {
25+
26+
// set debug mode (--cli-debug)
27+
utils.setDebugMode(args);
28+
2529
let bsConfigPath = utils.getConfigPath(args.cf);
30+
logger.debug(`browserstack.json path : ${bsConfigPath}`);
2631
//Delete build_results.txt from log folder if already present.
2732
initTimeComponents();
2833
instrumentEventTime("cliStart")
@@ -31,9 +36,12 @@ module.exports = function run(args, rawArgs) {
3136
markBlockEnd('deleteOldResults');
3237

3338
markBlockStart('validateBstackJson');
39+
logger.debug('Started browserstack.json validation');
3440
return utils.validateBstackJson(bsConfigPath).then(async function (bsConfig) {
3541
markBlockEnd('validateBstackJson');
42+
logger.debug('Completed browserstack.json validation');
3643
markBlockStart('setConfig');
44+
logger.debug('Started setting the configs');
3745
utils.setUsageReportingFlag(bsConfig, args.disableUsageReporting);
3846

3947
utils.setDefaults(bsConfig, args);
@@ -83,6 +91,9 @@ module.exports = function run(args, rawArgs) {
8391
// set the no-wrap
8492
utils.setNoWrap(bsConfig, args);
8593

94+
// set record feature caps
95+
utils.setRecordCaps(bsConfig, args);
96+
8697
//set browsers
8798
await utils.setBrowsers(bsConfig, args);
8899

@@ -95,12 +106,16 @@ module.exports = function run(args, rawArgs) {
95106
// set other cypress configs e.g. reporter and reporter-options
96107
utils.setOtherConfigs(bsConfig, args);
97108
markBlockEnd('setConfig');
109+
logger.debug("Completed setting the configs");
98110

99111
// Validate browserstack.json values and parallels specified via arguments
100112
markBlockStart('validateConfig');
113+
logger.debug("Started configs validation");
101114
return capabilityHelper.validate(bsConfig, args).then(function (cypressJson) {
102115
markBlockEnd('validateConfig');
116+
logger.debug("Completed configs validation");
103117
markBlockStart('preArchiveSteps');
118+
logger.debug("Started pre-archive steps");
104119
//get the number of spec files
105120
let specFiles = utils.getNumberOfSpecFiles(bsConfig, args, cypressJson);
106121

@@ -115,36 +130,51 @@ module.exports = function run(args, rawArgs) {
115130
// warn if specFiles cross our limit
116131
utils.warnSpecLimit(bsConfig, args, specFiles, rawArgs);
117132
markBlockEnd('preArchiveSteps');
133+
logger.debug("Completed pre-archive steps");
118134
markBlockStart('zip');
135+
logger.debug("Checking if test suite zip and dependencies is already available on browserstack");
119136
markBlockStart('zip.checkAlreadyUploaded');
120137
return checkUploaded.checkUploadedMd5(bsConfig, args, {markBlockStart, markBlockEnd}).then(function (md5data) {
121138
markBlockEnd('zip.checkAlreadyUploaded');
139+
logger.debug("Completed checking if test suite zip and dependencies already uploaded");
122140

141+
logger.debug("Started caching npm dependencies.");
123142
markBlockStart('zip.packageInstaller');
124143
return packageInstaller.packageWrapper(bsConfig, config.packageDirName, config.packageFileName, md5data, {markBlockStart, markBlockEnd}).then(function (packageData) {
144+
logger.debug("Completed caching npm dependencies.")
125145
markBlockEnd('zip.packageInstaller');
126146

127147
// Archive the spec files
148+
logger.debug("Started archiving test suite");
128149
markBlockStart('zip.archive');
129150
return archiver.archive(bsConfig.run_settings, config.fileName, args.exclude, md5data).then(function (data) {
151+
logger.debug("Completed archiving test suite");
130152
markBlockEnd('zip.archive');
131153

132154
let test_zip_size = utils.fetchZipSize(path.join(process.cwd(), config.fileName));
133155
let npm_zip_size = utils.fetchZipSize(path.join(process.cwd(), config.packageFileName));
134156

135157
// Uploaded zip file
158+
logger.debug("Started uploading the test suite zip");
159+
logger.debug("Started uploading the node_module zip");
136160
markBlockStart('zip.zipUpload');
137161
return zipUploader.zipUpload(bsConfig, md5data, packageData).then(async function (zip) {
162+
logger.debug("Completed uploading the test suite zip");
163+
logger.debug("Completed uploading the node_module zip");
138164
markBlockEnd('zip.zipUpload');
139165
markBlockEnd('zip');
140166

141167
// Create build
142168
//setup Local Testing
143169
markBlockStart('localSetup');
170+
logger.debug("Started setting up BrowserStack Local connection");
144171
let bs_local = await utils.setupLocalTesting(bsConfig, args, rawArgs);
172+
logger.debug('Completed setting up BrowserStack Local connection');
145173
markBlockEnd('localSetup');
174+
logger.debug("Started build creation");
146175
markBlockStart('createBuild');
147176
return build.createBuild(bsConfig, zip).then(function (data) {
177+
logger.debug("Completed build creation");
148178
markBlockEnd('createBuild');
149179
markBlockEnd('total');
150180
utils.setProcessHooks(data.build_id, bsConfig, bs_local, args);
@@ -177,7 +207,9 @@ module.exports = function run(args, rawArgs) {
177207

178208

179209
if (args.sync) {
210+
logger.debug("Started polling build status from BrowserStack");
180211
syncRunner.pollBuildStatus(bsConfig, data, rawArgs).then(async (exitCode) => {
212+
logger.debug("Completed polling of build status");
181213

182214
// stop the Local instance
183215
await utils.stopLocalBinary(bsConfig, bs_local, args, rawArgs);
@@ -188,6 +220,7 @@ module.exports = function run(args, rawArgs) {
188220
// download build artifacts
189221
if (exitCode != Constants.BUILD_FAILED_EXIT_CODE) {
190222
if (utils.nonEmptyArray(bsConfig.run_settings.downloads)) {
223+
logger.debug("Downloading build artifacts");
191224
await downloadBuildArtifacts(bsConfig, data.build_id, args, rawArgs);
192225
}
193226

bin/helpers/archiver.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const archiver = require("archiver"),
1010
const archiveSpecs = (runSettings, filePath, excludeFiles, md5data) => {
1111
return new Promise(function (resolve, reject) {
1212
if (md5data.zipUrlPresent) {
13+
logger.debug("Skipping test suite upload since BrowserStack already has your test suite that has not changed since the last run.");
1314
return resolve('Zipping not required');
1415
}
1516
var output = fs.createWriteStream(filePath);
@@ -55,6 +56,7 @@ const archiveSpecs = (runSettings, filePath, excludeFiles, md5data) => {
5556
archive.pipe(output);
5657

5758
let ignoreFiles = utils.getFilesToIgnore(runSettings, excludeFiles);
59+
logger.debug(`Patterns ignored during zip ${ignoreFiles}`);
5860
archive.glob(`**/*.+(${Constants.allowedFileTypes.join("|")})`, { cwd: cypressFolderPath, matchBase: true, ignore: ignoreFiles, dot:true });
5961

6062
let packageJSON = {};

bin/helpers/buildArtifacts.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ const sendUpdatesToBstack = async (bsConfig, buildId, args, options, rawArgs) =>
162162
request.post(options, function (err, resp, data) {
163163
if(err) {
164164
utils.sendUsageReport(bsConfig, args, err, Constants.messageTypes.ERROR, 'api_failed_build_artifacts_status_update', null, rawArgs);
165-
logger.error(utils.formatRequest(err, resp, body));
165+
logger.error(utils.formatRequest(err, resp, data));
166166
reject(err);
167167
} else {
168168
try {

bin/helpers/capabilityHelper.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ const addCypressZipStartLocation = (runSettings) => {
146146
let resolvedCypressConfigFilePath = path.resolve(runSettings.cypressConfigFilePath);
147147
runSettings.cypressZipStartLocation = path.dirname(resolvedCypressConfigFilePath.split(resolvedHomeDirectoryPath)[1]);
148148
runSettings.cypressZipStartLocation = runSettings.cypressZipStartLocation.substring(1);
149+
logger.debug(`Setting cypress zip start location = ${runSettings.cypressZipStartLocation}`);
149150
}
150151

151152
const validate = (bsConfig, args) => {
@@ -190,8 +191,10 @@ const validate = (bsConfig, args) => {
190191
let cypressConfigFilePath = bsConfig.run_settings.cypressConfigFilePath;
191192
let cypressJson = {};
192193

194+
logger.debug(`Checking for cypress config file at ${cypressConfigFilePath}`);
193195
if (!fs.existsSync(cypressConfigFilePath) && bsConfig.run_settings.cypress_config_filename !== 'false') reject(Constants.validationMessages.INVALID_CYPRESS_CONFIG_FILE);
194196

197+
logger.debug("Validating cypress.json");
195198
try {
196199
if (bsConfig.run_settings.cypress_config_filename !== 'false') {
197200
let cypressJsonContent = fs.readFileSync(cypressConfigFilePath);
@@ -210,6 +213,7 @@ const validate = (bsConfig, args) => {
210213
//check if home_directory is present or not in user run_settings
211214
if (!Utils.isUndefined(bsConfig.run_settings.home_directory)) {
212215
// check if home_directory exists or not
216+
logger.debug(`Validating home_directory at ${bsConfig.run_settings.home_directory}`);
213217
if (!fs.existsSync(bsConfig.run_settings.home_directory)) {
214218
reject(Constants.validationMessages.HOME_DIRECTORY_NOT_FOUND);
215219
}
@@ -241,6 +245,15 @@ const validate = (bsConfig, args) => {
241245
logger.warn(Constants.validationMessages.SPEC_TIMEOUT_NOT_PASSED_ERROR);
242246
}
243247

248+
if(!Utils.isUndefined(bsConfig.run_settings["record"]) && String(bsConfig.run_settings["record"]) == 'true') {
249+
if(Utils.isUndefined(bsConfig.run_settings.projectId) || bsConfig.run_settings.projectId == "" ) {
250+
logger.warn(Constants.validationMessages.PROJECT_ID_MISSING);
251+
}
252+
if (Utils.isUndefined(bsConfig.run_settings["record-key"]) || bsConfig.run_settings["record-key"] == "" ) {
253+
logger.warn(Constants.validationMessages.RECORD_KEY_MISSING);
254+
}
255+
}
256+
244257
resolve(cypressJson);
245258
});
246259
}

bin/helpers/checkUploaded.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ const crypto = require('crypto'),
77
config = require('./config'),
88
path = require('path'),
99
fs = require("fs"),
10-
utils = require('./utils');
10+
utils = require('./utils'),
11+
logger = require('./logger').winstonLogger;
1112

1213

1314
const checkSpecsMd5 = (runSettings, args, instrumentBlocks) => {
@@ -83,6 +84,7 @@ const checkUploadedMd5 = (bsConfig, args, instrumentBlocks) => {
8384
packageUrlPresent: false,
8485
};
8586
if (args["force-upload"]) {
87+
logger.debug("force-upload set to true. Uploading tests and npm packages.");
8688
return resolve(obj);
8789
}
8890

bin/helpers/constants.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ const userMessages = {
2121
ZIP_UPLOADER_NOT_REACHABLE: "Could not reach BrowserStack APIs. Please check your network or see if you need to whitelist *.browserstack.com",
2222
ZIP_UPLOAD_FAILED: "Zip Upload failed.",
2323
ZIP_UPLOAD_LIMIT_EXCEEDED: "The directory size which contains the cypress config file is more than 200 MB. For more info, check out https://www.browserstack.com/docs/automate/cypress/exclude-files",
24+
NODE_MODULES_LIMIT_EXCEEDED: "node_modules upload failed as the size %SIZE% MB is not supported. Dependencies will be installed in runtime. This will have a negative impact on build performance. Reach out to us at browserstack.com/support if you see this warning.",
2425
CONFIG_FILE_CREATED: "BrowserStack Config File created, you can now run browserstack-cypress --config-file run",
2526
CONFIG_FILE_EXISTS: "File already exists, delete the browserstack.json file manually. skipping...",
2627
DIR_NOT_FOUND: "Given path does not exist. Failed to create browserstack.json in %s",
@@ -101,7 +102,9 @@ const validationMessages = {
101102
HOME_DIRECTORY_NOT_A_DIRECTORY: "Specified home directory is not a directory. The home directory can only be a directory and not a file.",
102103
CYPRESS_CONFIG_FILE_NOT_PART_OF_HOME_DIRECTORY: "Could not find cypress.json within the specified home directory. Please make sure cypress.json resides within the home directory.",
103104
SPEC_TIMEOUT_LIMIT_ERROR: "The maximum allowed value of 'spec_timeout' is 120. Read more on https://browserstack.com/docs/automate/cypress/spec-timeout ",
104-
SPEC_TIMEOUT_NOT_PASSED_ERROR: "'spec_timeout' key not specified. Going ahead with 30 mins as the default spec timeout. Read more about how to specify the option in https://browserstack.com/docs/automate/cypress/spec-timeout "
105+
SPEC_TIMEOUT_NOT_PASSED_ERROR: "'spec_timeout' key not specified. Going ahead with 30 mins as the default spec timeout. Read more about how to specify the option in https://browserstack.com/docs/automate/cypress/spec-timeout ",
106+
PROJECT_ID_MISSING: "You have specified '--record' flag but you've not provided the 'projectId' in cypress.json or in browserstack.json. Your record functionality on cypress.io dashboard might not work as it needs both the key and the projectId",
107+
RECORD_KEY_MISSING: "You have specified '--record' flag but you've not provided the '--record-key' and we could not find any value in 'CYPRESS_RECORD_KEY' environment variable. Your record functionality on cypress.io dashboard might not work as it needs the key and projectId"
105108
};
106109

107110
const cliMessages = {
@@ -145,7 +148,10 @@ const cliMessages = {
145148
REPORTER: "Specify the custom reporter to use",
146149
REPORTER_OPTIONS: "Specify reporter options for custom reporter",
147150
CYPRESS_GEO_LOCATION: "Enterprise feature to simulate website and mobile behavior from different locations.",
148-
SPEC_TIMEOUT: "Specify a value for a hard timeout for each spec execution in the 1-120 mins range. Read https://browserstack.com/docs/automate/cypress/spec-timeout for more details."
151+
SPEC_TIMEOUT: "Specify a value for a hard timeout for each spec execution in the 1-120 mins range. Read https://browserstack.com/docs/automate/cypress/spec-timeout for more details.",
152+
RECORD: "Pass the --record flag to record your Cypress runs on Cypress.io dashboard. Note: You also need to specify '--record-key' and '--projectId' arguments either in CLI or in browserstack.json.",
153+
RECORD_KEY: "You can specify the 'key' that is needed to record your runs on Cypress.io dashboard using the '--record-key' argument. Alternatively, you can also pass it on browserstack.json",
154+
PROJECT_ID: "You can pass the 'projectId' of your Cypress.io project where you want to record your runs if specifying the '--record' key. You can also specify this in your cypress.json or in your browserstack.json."
149155
},
150156
COMMON: {
151157
DISABLE_USAGE_REPORTING: "Disable usage reporting",
@@ -155,6 +161,7 @@ const cliMessages = {
155161
NO_NPM_WARNING: "No NPM warning if npm_dependencies is empty",
156162
CONFIG_DEMAND: "config file is required",
157163
CONFIG_FILE_PATH: "Path to BrowserStack config",
164+
DEBUG: "Use this option to get debug logs on the CLI console.",
158165
},
159166
GENERATE_REPORT: {
160167
INFO: "Generates the build report"
@@ -245,6 +252,8 @@ const REDACTED_AUTH =`auth: { "username": ${REDACTED}, "access_key": ${REDACTED}
245252

246253
const SPEC_TIMEOUT_LIMIT = 120 // IN MINS
247254

255+
const CYPRESS_CUSTOM_ERRORS_TO_PRINT_KEY = "custom_errors_to_print";
256+
248257
module.exports = Object.freeze({
249258
syncCLI,
250259
userMessages,
@@ -269,5 +278,6 @@ module.exports = Object.freeze({
269278
REDACTED_AUTH,
270279
REDACTED,
271280
BUILD_FAILED_EXIT_CODE,
272-
SPEC_TIMEOUT_LIMIT
281+
SPEC_TIMEOUT_LIMIT,
282+
CYPRESS_CUSTOM_ERRORS_TO_PRINT_KEY
273283
});

bin/helpers/fileHelpers.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ exports.deletePackageArchieve = (logging = true) => {
4545
return 0;
4646
} catch (err) {
4747
if (logging) logger.info(Constants.userMessages.NPM_DELETE_FAILED);
48+
logger.debug("Could not delete the dependency packages with error :", err);
4849
return 1;
4950
}
5051
};

bin/helpers/logger.js

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,37 +8,47 @@ if (!fs.existsSync(logDir)) {
88
fs.mkdirSync(logDir);
99
}
1010

11+
// Save transports to change log level dynamically
12+
const transports = {
13+
loggerConsole: new winston.transports.Console({
14+
name: 'console.info',
15+
colorize: true,
16+
timestamp: function () {
17+
return `[${new Date().toLocaleString()}]`;
18+
},
19+
prettyPrint: true,
20+
}),
21+
syncLoggerConsole: new (winston.transports.Console)({
22+
formatter: (options) => {
23+
return (options.message ? options.message : '');
24+
}
25+
}),
26+
loggerFile: new winston.transports.File({
27+
filename: path.join(logDir, "/usage.log"),
28+
}),
29+
}
30+
1131
const winstonLoggerParams = {
1232
transports: [
13-
new winston.transports.Console({
14-
name: 'console.info',
15-
colorize: true,
16-
timestamp: function () {
17-
return `[${new Date().toLocaleString()}]`;
18-
},
19-
prettyPrint: true,
20-
}),
33+
transports.loggerConsole,
2134
],
2235
};
2336

2437
const winstonSyncCliLoggerParams = {
2538
transports: [
26-
new (winston.transports.Console)({
27-
formatter: (options) => {
28-
return (options.message ? options.message : '');
29-
}
30-
}),
39+
transports.syncLoggerConsole,
3140
]
3241
}
3342

3443
const winstonFileLoggerParams = {
3544
transports: [
36-
new winston.transports.File({
37-
filename: path.join(logDir, "/usage.log"),
38-
}),
45+
transports.loggerFile,
3946
],
4047
};
4148

4249
exports.winstonLogger = new winston.Logger(winstonLoggerParams);
4350
exports.fileLogger = new winston.Logger(winstonFileLoggerParams);
4451
exports.syncCliLogger = new winston.Logger(winstonSyncCliLoggerParams);
52+
53+
//Export transports to change log level
54+
exports.transports = transports;

0 commit comments

Comments
 (0)