Skip to content

Commit 8b75f38

Browse files
Merge pull request #82 from browserstack/sync-cli-log-changes
Cli changes for sync cli
2 parents 7227e2c + 390a491 commit 8b75f38

19 files changed

+164
-205
lines changed

bin/commands/runs.js

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ const archiver = require("../helpers/archiver"),
88
Constants = require("../helpers/constants"),
99
utils = require("../helpers/utils"),
1010
fileHelpers = require("../helpers/fileHelpers"),
11-
syncRunner = require("../helpers/syncRunner");
11+
syncRunner = require("../helpers/syncRunner"),
12+
syncCliLogger = require("../helpers/logger").syncCliLogger;
1213

1314
module.exports = function run(args) {
1415
let bsConfigPath = utils.getConfigPath(args.cf);
@@ -47,7 +48,6 @@ module.exports = function run(args) {
4748

4849
// Validate browserstack.json values and parallels specified via arguments
4950
return capabilityHelper.validate(bsConfig, args).then(function (validated) {
50-
logger.info(validated);
5151

5252
// accept the number of parallels
5353
utils.setParallels(bsConfig, args);
@@ -57,7 +57,6 @@ module.exports = function run(args) {
5757

5858
// Uploaded zip file
5959
return zipUploader.zipUpload(bsConfig, config.fileName).then(function (zip) {
60-
6160
// Create build
6261
return build.createBuild(bsConfig, zip).then(function (data) {
6362
let message = `${data.message}! ${Constants.userMessages.BUILD_CREATED} with build id: ${data.build_id}`;
@@ -67,19 +66,22 @@ module.exports = function run(args) {
6766
logger.warn(Constants.userMessages.NO_PARALLELS);
6867
}
6968

70-
if (!args.disableNpmWarning && bsConfig.run_settings.npm_dependencies && Object.keys(bsConfig.run_settings.npm_dependencies).length <= 0) logger.warn(Constants.userMessages.NO_NPM_DEPENDENCIES);
71-
69+
if (!args.disableNpmWarning && bsConfig.run_settings.npm_dependencies && Object.keys(bsConfig.run_settings.npm_dependencies).length <= 0) {
70+
logger.warn(Constants.userMessages.NO_NPM_DEPENDENCIES);
71+
logger.warn(Constants.userMessages.NO_NPM_DEPENDENCIES_READ_MORE);
72+
}
7273
if (args.sync) {
7374
syncRunner.pollBuildStatus(bsConfig, data).then((exitCode) => {
7475
utils.sendUsageReport(bsConfig, args, `${message}\n${dashboardLink}`, Constants.messageTypes.SUCCESS, null);
75-
logger.info(Constants.userMessages.BUILD_REPORT_MESSAGE);
76-
logger.info(data.dashboard_url)
76+
syncCliLogger.info(Constants.userMessages.BUILD_REPORT_MESSAGE);
77+
syncCliLogger.info(data.dashboard_url);
7778
process.exit(exitCode);
7879
});
7980
}
8081

8182
logger.info(message);
8283
logger.info(dashboardLink);
84+
if(!args.sync) logger.info(Constants.userMessages.EXIT_SYNC_CLI_MESSAGE.replace("<build-id>",data.build_id));
8385
utils.sendUsageReport(bsConfig, args, `${message}\n${dashboardLink}`, Constants.messageTypes.SUCCESS, null);
8486
return;
8587
}).catch(function (err) {
@@ -91,9 +93,8 @@ module.exports = function run(args) {
9193
// Zip Upload failed
9294
logger.error(err);
9395
logger.error(Constants.userMessages.ZIP_UPLOAD_FAILED);
94-
utils.sendUsageReport(bsConfig, args, `${err}\n${Constants.userMessages.ZIP_UPLOAD_FAILED}`, Constants.messageTypes.ERROR, 'zip_upload_failed');
95-
}).finally(function () {
9696
fileHelpers.deleteZip();
97+
utils.sendUsageReport(bsConfig, args, `${err}\n${Constants.userMessages.ZIP_UPLOAD_FAILED}`, Constants.messageTypes.ERROR, 'zip_upload_failed');
9798
});
9899
}).catch(function (err) {
99100
// Zipping failed

bin/helpers/archiver.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ const archiveSpecs = (runSettings, filePath, excludeFiles) => {
1313

1414
var cypressFolderPath = path.dirname(runSettings.cypressConfigFilePath);
1515

16+
logger.info(`Creating tests.zip with files in ${cypressFolderPath}`);
17+
1618
var archive = archiver('zip', {
1719
zlib: { level: 9 } // Sets the compression level.
1820
});

bin/helpers/capabilityHelper.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,30 +20,32 @@ const caps = (bsConfig, zip) => {
2020

2121
// Browser list
2222
let osBrowserArray = [];
23+
let browsersList = [];
2324
if (bsConfig.browsers) {
2425
bsConfig.browsers.forEach((element) => {
2526
osBrowser = element.os + "-" + element.browser;
27+
osAndBrowser = element.os + " / " + Utils.capitalizeFirstLetter(element.browser);
2628
element.versions.forEach((version) => {
2729
osBrowserArray.push(osBrowser + version);
30+
browsersList.push(`${osAndBrowser} (${version})`);
2831
});
2932
});
3033
}
3134
obj.devices = osBrowserArray;
3235
if (obj.devices.length == 0) reject(Constants.validationMessages.EMPTY_BROWSER_LIST);
33-
logger.info(`Browser list: ${osBrowserArray.toString()}`);
36+
logger.info(`Browsers list: ${browsersList.join(", ")}`);
3437

3538
// Test suite
3639
if (zip.zip_url && zip.zip_url.split("://")[1].length !== 0) {
3740
obj.test_suite = zip.zip_url.split("://")[1];
3841
} else {
3942
reject("Test suite is empty");
4043
}
41-
logger.info(`Test suite: bs://${obj.test_suite}`);
4244

4345
// Local
4446
obj.local = false;
4547
if (bsConfig.connection_settings && bsConfig.connection_settings.local === true) obj.local = true;
46-
logger.info(`Local is set to: ${obj.local}`);
48+
logger.info(`Local is set to: ${obj.local} (${obj.local ? Constants.userMessages.LOCAL_TRUE : Constants.userMessages.LOCAL_FALSE})`);
4749

4850
// Local Identifier
4951
obj.localIdentifier = null;
@@ -100,6 +102,7 @@ const caps = (bsConfig, zip) => {
100102

101103
const validate = (bsConfig, args) => {
102104
return new Promise(function (resolve, reject) {
105+
logger.info(Constants.userMessages.VALIDATING_CONFIG);
103106
if (!bsConfig) reject(Constants.validationMessages.EMPTY_BROWSERSTACK_JSON);
104107

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

bin/helpers/constants.js

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const syncCLI = {
22
FAILED_SPEC_DETAILS_COL_HEADER: ['Spec', 'Status', 'Browser', 'BrowserStack Session ID'],
33
LOGS: {
4-
INIT_LOG: "Running Tests: ..."
4+
INIT_LOG: "All tests:"
55
},
66
INITIAL_DELAY_MULTIPLIER: 10
77
};
@@ -17,14 +17,20 @@ const userMessages = {
1717
CONFIG_FILE_CREATED: "BrowserStack Config File created, you can now run browserstack-cypress --config-file run",
1818
CONFIG_FILE_EXISTS: "File already exists, delete the browserstack.json file manually. skipping...",
1919
DIR_NOT_FOUND: "Given path does not exist. Failed to create browserstack.json in %s",
20-
ZIP_DELETE_FAILED: "Could not delete local file.",
21-
ZIP_DELETED: "Zip file deleted successfully.",
20+
ZIP_DELETE_FAILED: "Could not delete tests.zip successfully.",
21+
ZIP_DELETED: "Deleted tests.zip successfully.",
2222
API_DEPRECATED: "This version of API is deprecated, please use latest version of API.",
2323
FAILED_TO_ZIP: "Failed to zip files.",
24-
VISIT_DASHBOARD: "Visit the Automate dashboard for test reporting:",
24+
VISIT_DASHBOARD: "Visit the Automate dashboard for real-time test reporting:",
2525
CONFLICTING_INIT_ARGUMENTS: "Conflicting arguments given. You can use --path only with a file name, and not with a file path.",
26-
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",
27-
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."
26+
NO_PARALLELS: "Your specs will run sequentially on a single machine. Read more about running your specs in parallel here: https://www.browserstack.com/docs/automate/cypress/run-tests-in-parallel",
27+
NO_NPM_DEPENDENCIES: "No npm dependencies specified - your specs might fail if they need any packages to be installed before running.",
28+
NO_NPM_DEPENDENCIES_READ_MORE: "Read more about npm dependencies here: https://www.browserstack.com/docs/automate/cypress/npm-packages. You can suppress this warning by using --disable-npm-warning flag.",
29+
VALIDATING_CONFIG: "Validating the config",
30+
UPLOADING_TESTS: "Uploading the tests to BrowserStack",
31+
LOCAL_TRUE: "you will now be able to test localhost / private URLs",
32+
LOCAL_FALSE: "you won't be able to test localhost / private URLs",
33+
EXIT_SYNC_CLI_MESSAGE: "Exiting the CLI, but your build is still running. You can use the --sync option to keep getting test updates. You can also use the build-info <build-id> command now."
2834
};
2935

3036
const validationMessages = {

bin/helpers/fileHelpers.js

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@
22
const fs = require('fs-extra'),
33
path = require('path');
44

5-
const logger = require("./logger").winstonLogger,
6-
Constants = require("../helpers/constants"),
7-
config = require("../helpers/config");
5+
const logger = require('./logger').winstonLogger,
6+
Constants = require('../helpers/constants'),
7+
config = require('../helpers/config');
88

9-
exports.write = function(f, message, args, cb) {
9+
exports.write = function (f, message, args, cb) {
1010
message = message || 'Creating';
11-
fs.writeFile(f.path, f.file, function() {
12-
logger.info(message + " file: " + f.path);
13-
cb && cb(args)
11+
fs.writeFile(f.path, f.file, function () {
12+
logger.info(message + ' file: ' + f.path);
13+
cb && cb(args);
1414
});
15-
}
15+
};
1616

1717
exports.fileExists = function (filePath, cb) {
1818
fs.access(filePath, fs.F_OK, (err) => {
@@ -25,21 +25,20 @@ exports.fileExists = function (filePath, cb) {
2525
};
2626

2727
exports.deleteZip = () => {
28-
return fs.unlink(config.fileName, function (err) {
29-
if (err) {
30-
logger.info(Constants.userMessages.ZIP_DELETE_FAILED);
31-
return 1;
32-
} else {
33-
logger.info(Constants.userMessages.ZIP_DELETED);
34-
return 0;
35-
}
36-
});
37-
}
28+
try {
29+
fs.unlinkSync(config.fileName);
30+
logger.info(Constants.userMessages.ZIP_DELETED);
31+
return 0;
32+
} catch (err) {
33+
logger.info(Constants.userMessages.ZIP_DELETE_FAILED);
34+
return 1;
35+
}
36+
};
3837

3938
exports.dirExists = function (filePath, cb) {
4039
let exists = false;
4140
if (fs.existsSync(path.dirname(filePath), cb)) {
4241
exists = true;
4342
}
4443
cb && cb(exists);
45-
}
44+
};

bin/helpers/sync/failedSpecsDetails.js

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ const tablePrinter = require('table'), // { table, getBorderCharacters }
1919
//
2020
let failedSpecsDetails = (data) => {
2121
return new Promise((resolve, reject) => {
22-
if (data.length === 0) resolve(0); // return if no failed/skipped tests.
22+
data.exitCode = 0;
23+
if (data.specs.length === 0) resolve(data); // return if no failed/skipped tests.
2324

2425
let failedSpecs = false;
2526
let specResultHeader = Constants.syncCLI.FAILED_SPEC_DETAILS_COL_HEADER.map((col) => {
@@ -28,16 +29,23 @@ let failedSpecsDetails = (data) => {
2829

2930
let specData = [specResultHeader]; // 2-D array
3031

31-
data.forEach((spec) => {
32+
data.specs.forEach((spec) => {
3233
if (spec.status.toLowerCase() === 'passed') {
3334
return;
3435
}
3536
if (spec.status && spec.status.toLowerCase() === 'failed' && !failedSpecs)
3637
failedSpecs = true;
3738

38-
let specStatus = (spec.status && spec.status.toLowerCase() === 'failed') ?
39-
chalk.red(spec.status) : chalk.yellow(spec.status);
40-
specData.push([spec.specName, specStatus, spec.combination, spec.sessionId]);
39+
let specStatus =
40+
spec.status && spec.status.toLowerCase() === 'failed'
41+
? chalk.red(spec.status)
42+
: chalk.yellow(spec.status);
43+
specData.push([
44+
spec.specName,
45+
specStatus,
46+
spec.combination,
47+
spec.sessionId,
48+
]);
4149
});
4250

4351
let config = {
@@ -61,11 +69,11 @@ let failedSpecsDetails = (data) => {
6169

6270
let result = tablePrinter.table(specData, config);
6371

64-
logger.info('Failed / skipped test report');
72+
logger.info('\nFailed / skipped test report:');
6573
logger.info(result);
6674

67-
if (failedSpecs) reject(1); // specs failed, send exitCode as 1
68-
resolve(0); // No Specs failed, maybe skipped, but not failed, send exitCode as 0
75+
if (failedSpecs) data.exitCode = 1 ; // specs failed, send exitCode as 1
76+
resolve(data); // No Specs failed, maybe skipped, but not failed, send exitCode as 0
6977
});
7078
}
7179

bin/helpers/sync/specsSummary.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const logger = require("../logger").syncCliLogger;
1616
// {specName: 'spec8.alias.js', status: 'Skipped', combination: 'Win 10 / Chrome 78', sessionId: '3d3rdf3r...'}
1717
// ]
1818
//
19-
let printSpecsRunSummary = (data, time, machines) => {
19+
let printSpecsRunSummary = (data, machines) => {
2020
return new Promise((resolve, _reject) => {
2121
let summary = {
2222
total: 0,
@@ -25,14 +25,14 @@ let printSpecsRunSummary = (data, time, machines) => {
2525
skipped: 0
2626
};
2727

28-
data.forEach((spec) => {
28+
data.specs.forEach((spec) => {
2929
specSummaryCount(summary, spec.status.toLowerCase());
3030
});
3131

3232
logger.info(`Total tests: ${summary.total}, passed: ${summary.passed}, failed: ${summary.failed}, skipped: ${summary.skipped}`);
33-
logger.info(`Done in ${time/1000} seconds using ${machines} machines\n`);
33+
logger.info(`Done in ${data.duration/1000} seconds using ${machines} machines\n`);
3434

35-
resolve(data);
35+
resolve(data.exitCode);
3636
})
3737
};
3838

bin/helpers/sync/syncSpecsLogs.js

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,25 +32,25 @@ let getOptions = (auth, build_id) => {
3232
let getTableConfig = () => {
3333
return {
3434
border: getBorderConfig(),
35-
singleLine: true,
3635
columns: {
37-
0: { alignment: 'right' }
36+
1: {alignment: 'center', width: 1},
37+
2: {alignment: 'left', width: 50}
3838
},
3939
columnDefault: {
40-
width: 50
40+
width: 25,
4141
},
42-
columnCount: 2
42+
columnCount: 3,
4343
};
4444
}
4545

4646
let getBorderConfig = () => {
4747
return {
48-
topBody: `-`,
48+
topBody: ``,
4949
topJoin: ``,
5050
topLeft: ``,
5151
topRight: ``,
5252

53-
bottomBody: `-`,
53+
bottomBody: ``,
5454
bottomJoin: ``,
5555
bottomLeft: ``,
5656
bottomRight: ``,
@@ -81,7 +81,6 @@ let printSpecsStatus = (bsConfig, buildDetails) => {
8181
},
8282
function(err, result) { // when loop ends
8383
specSummary.duration = endTime - startTime
84-
logger.info();
8584
resolve(specSummary)
8685
}
8786
);
@@ -105,6 +104,7 @@ let whileProcess = (whilstCallback) => {
105104
whileLoop = false;
106105
endTime = Date.now();
107106
showSpecsStatus(body);
107+
logger.info("\n--------------------------------------------------------------------------------")
108108
return whilstCallback(null, body);
109109
default:
110110
whileLoop = false;
@@ -126,7 +126,8 @@ let showSpecsStatus = (data) => {
126126

127127
let printInitialLog = () => {
128128
startTime = Date.now();
129-
logger.info(Constants.syncCLI.LOGS.INIT_LOG)
129+
logger.info(`\n${Constants.syncCLI.LOGS.INIT_LOG}`)
130+
logger.info("--------------------------------------------------------------------------------")
130131
n = Constants.syncCLI.INITIAL_DELAY_MULTIPLIER
131132
}
132133

@@ -138,7 +139,7 @@ let printSpecData = (data) => {
138139
}
139140

140141
let writeToTable = (combination, specName, status) => {
141-
stream.write([combination + ":", `${specName} ${status}`]);
142+
stream.write([combination , ":", `${specName} ${status}`]);
142143
}
143144

144145
let addSpecToSummary = (specName, status, combination, session_id) => {
@@ -152,7 +153,7 @@ let addSpecToSummary = (specName, status, combination, session_id) => {
152153
}
153154

154155
let getCombinationName = (spec) => {
155-
return `${spec["os"]} ${spec["osVersion"]} / ${spec["browser"]} ${spec["browserVersion"]}`
156+
return `${utils.capitalizeFirstLetter(spec['browser'])} ${spec['browserVersion']} (${spec['os']} ${spec['osVersion']})`;
156157
}
157158

158159
let getStatus = (status) => {

0 commit comments

Comments
 (0)