Skip to content

Commit 7d0f551

Browse files
committed
Merge branch 'sync-cli' of github.com:browserstack/browserstack-cypress-cli into CYP_442_sync_cli_part_1
2 parents f165b56 + daea598 commit 7d0f551

File tree

8 files changed

+164
-41
lines changed

8 files changed

+164
-41
lines changed

bin/helpers/constants.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1+
const syncCLI = {
2+
FAILED_SPEC_DETAILS_COL_HEADER: ['Spec', 'Status', 'Browser', 'BrowserStack Session ID']
3+
};
4+
15
const userMessages = {
26
BUILD_FAILED: "Build creation failed.",
37
BUILD_CREATED: "Build created",
48
BUILD_INFO_FAILED: "Failed to get build info.",
59
BUILD_STOP_FAILED: "Failed to stop build.",
6-
BUILD_REPORT_MESDSAGE: "See the entire build report here:",
10+
BUILD_REPORT_MESSAGE: "See the entire build report here:",
711
ZIP_UPLOADER_NOT_REACHABLE: "Could not reach to zip uploader.",
812
ZIP_UPLOAD_FAILED: "Zip Upload failed.",
913
CONFIG_FILE_CREATED: "BrowserStack Config File created, you can now run browserstack-cypress --config-file run",
@@ -95,6 +99,7 @@ const allowedFileTypes = ['js', 'json', 'txt', 'ts', 'feature', 'features', 'pdf
9599
const filesToIgnoreWhileUploading = ['node_modules/**', 'package-lock.json', 'package.json', 'browserstack-package.json', 'tests.zip', 'cypress.json']
96100

97101
module.exports = Object.freeze({
102+
syncCLI,
98103
userMessages,
99104
cliMessages,
100105
validationMessages,

bin/helpers/logger.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,16 @@ const winstonLoggerParams = {
2121
],
2222
};
2323

24+
const winstonSyncCliLoggerParams = {
25+
transports: [
26+
new (winston.transports.Console)({
27+
formatter: (options) => {
28+
return (options.message ? options.message : '');
29+
}
30+
}),
31+
]
32+
}
33+
2434
const winstonFileLoggerParams = {
2535
transports: [
2636
new winston.transports.File({
@@ -31,3 +41,4 @@ const winstonFileLoggerParams = {
3141

3242
exports.winstonLogger = new winston.Logger(winstonLoggerParams);
3343
exports.fileLogger = new winston.Logger(winstonFileLoggerParams);
44+
exports.syncCliLogger = new winston.Logger(winstonSyncCliLoggerParams);
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
const tablePrinter = require('table'), // { table, getBorderCharacters }
2+
chalk = require('chalk'),
3+
Constants = require("../constants"),
4+
logger = require("../logger").syncCliLogger;
5+
6+
/**
7+
*
8+
* @param {Array.<{specName: string, status: string, combination: string, sessionId: string}>} data
9+
* @returns {Promise.resolve || Promise.reject}
10+
*/
11+
// Example:
12+
// [
13+
// {specName: 'spec1.failed.js', status: 'Failed', combination: 'Win 10 / Chrome 78', sessionId: '3d3rdf3r...'},
14+
// {specName: 'spec2.name.js', status: 'Skipped', combination: 'Win 10 / Chrome 78', sessionId: '3d3rdf3r...'},
15+
// {specName: 'spec3.network.js', status: 'Failed', combination: 'Win 10 / Chrome 78', sessionId: '3d3rdf3r...'},
16+
// {specName: 'spec6.utils.js', status: 'Failed', combination: 'Win 10 / Chrome 78', sessionId: '3d3rdf3r...'},
17+
// {specName: 'spec8.alias.js', status: 'Skipped', combination: 'Win 10 / Chrome 78', sessionId: '3d3rdf3r...'}
18+
// ]
19+
//
20+
let failedSpecsDetails = (data) => {
21+
return new Promise((resolve, reject) => {
22+
if (data.length === 0) resolve(0); // return if no failed/skipped tests.
23+
24+
let failedSpecs = false;
25+
let specResultHeader = Constants.syncCLI.FAILED_SPEC_DETAILS_COL_HEADER.map((col) => {
26+
return chalk.blueBright(col);
27+
});
28+
29+
let specData = [specResultHeader]; // 2-D array
30+
31+
data.forEach((spec) => {
32+
if (spec.status && spec.status.toLowerCase() === 'failed' && !failedSpecs)
33+
failedSpecs = true;
34+
35+
let specStatus = (spec.status && spec.status.toLowerCase() === 'failed') ?
36+
chalk.red(spec.status) : chalk.yellow(spec.status);
37+
specData.push([spec.specName, specStatus, spec.combination, spec.sessionId]);
38+
});
39+
40+
let config = {
41+
border: tablePrinter.getBorderCharacters('ramac'),
42+
columns: {
43+
0: { alignment: 'left' },
44+
1: { alignment: 'left' },
45+
2: { alignment: 'left' },
46+
3: { alignment: 'left' },
47+
},
48+
/**
49+
* @typedef {function} drawHorizontalLine
50+
* @param {number} index
51+
* @param {number} size
52+
* @return {boolean}
53+
*/
54+
drawHorizontalLine: (index, size) => {
55+
return (index === 0 || index === 1 || index === size);
56+
}
57+
}
58+
59+
let result = tablePrinter.table(specData, config);
60+
61+
logger.info('Failed / skipped test report');
62+
logger.info(result);
63+
64+
if (failedSpecs) reject(1); // specs failed, send exitCode as 1
65+
resolve(0); // No Specs failed, maybe skipped, but not failed, send exitCode as 0
66+
});
67+
}
68+
69+
exports.failedSpecsDetails = failedSpecsDetails;

bin/helpers/syncRunner.js

Lines changed: 21 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,27 @@
11
'use strict';
2-
const config = require("./config"),
3-
logger = require("./logger").winstonLogger,
2+
const Config = require("./config"),
3+
logger = require("./logger").syncCliLogger,
44
Constants = require("./constants"),
55
utils = require("./utils"),
6-
request = require('request');
6+
request = require('request'),
7+
specDetails = require('./sync/failedSpecsDetails'),
8+
{ table, getBorderCharacters } = require('table'),
9+
chalk = require('chalk');
710

811
exports.pollBuildStatus = (bsConfig, buildDetails) => {
9-
return new Promise(function (resolve, reject) {
10-
logBuildDetails(bsConfig, buildDetails);
11-
printSpecsStatus()
12-
.then((data) => {
13-
printSpecsRunSummary();
14-
})
15-
.then((data) => {
16-
printFailedSpecsDetails();
17-
})
18-
.then((data) => {
19-
printBuildDashboardLink(buildDetails.dashboard_url);
20-
// success case!
21-
resolve(0); // exit code 0
22-
})
23-
.catch((err) => {
24-
// failed case!
25-
reject(err); // exit code 1
26-
});
27-
});
12+
logBuildDetails(bsConfig, buildDetails);
13+
printSpecsStatus().then((data) => {
14+
printSpecsRunSummary();
15+
}).then((data) => {
16+
return specDetails.failedSpecsDetails(data);
17+
}).then((successExitCode) => {
18+
return resolveExitCode(successExitCode); // exit code 0
19+
}).catch((nonZeroExitCode) => {
20+
return resolveExitCode(nonZeroExitCode); // exit code 1
21+
}).finally(() => {
22+
logger.info(Constants.userMessages.BUILD_REPORT_MESSAGE);
23+
logger.info(`${Config.dashboardUrl}${buildDetails.dashboard_url}`);
24+
});
2825
};
2926

3027
let logBuildDetails = (bsConfig, buildDetails) => {
@@ -52,12 +49,6 @@ let printSpecsRunSummary = () => {
5249
});
5350
};
5451

55-
let printFailedSpecsDetails = () => {
56-
return new Promise(function (resolve, reject) {
57-
resolve();
58-
});
59-
};
60-
61-
let printBuildDashboardLink = (dashboardUrl) => {
62-
logger.info(`${Constants.cliMessages.RUN.BUILD_REPORT_MESSAGE}: ${dashboardUrl}`);
52+
let resolveExitCode = (exitCode) => {
53+
return new Promise((resolve, _reject) => { resolve(exitCode) });
6354
};

bin/helpers/utils.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ exports.isParallelValid = (value) => {
219219
}
220220

221221
exports.getUserAgent = () => {
222-
return `BStack-Cypress-CLI/1.4.0 (${os.arch()}/${os.platform()}/${os.release()})`;
222+
return `BStack-Cypress-CLI/1.5.0 (${os.arch()}/${os.platform()}/${os.release()})`;
223223
};
224224

225225
exports.isAbsolute = (configPath) => {

bin/templates/configTemplate.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,47 +8,47 @@ module.exports = function () {
88
{
99
"browser": "chrome",
1010
"os": "Windows 10",
11-
"versions": ["78", "77"]
11+
"versions": ["latest", "latest-1"]
1212
},
1313
{
1414
"browser": "firefox",
1515
"os": "Windows 10",
16-
"versions": ["74", "75"]
16+
"versions": ["latest", "latest-1"]
1717
},
1818
{
1919
"browser": "edge",
2020
"os": "Windows 10",
21-
"versions": ["80", "81"]
21+
"versions": ["latest", "latest-1"]
2222
},
2323
{
2424
"browser": "chrome",
2525
"os": "OS X Mojave",
26-
"versions": ["78", "77"]
26+
"versions": ["latest", "latest-1"]
2727
},
2828
{
2929
"browser": "firefox",
3030
"os": "OS X Mojave",
31-
"versions": ["74", "75"]
31+
"versions": ["latest", "latest-1"]
3232
},
3333
{
3434
"browser": "edge",
3535
"os": "OS X Mojave",
36-
"versions": ["80", "81"]
36+
"versions": ["latest", "latest-1"]
3737
},
3838
{
3939
"browser": "chrome",
4040
"os": "OS X Catalina",
41-
"versions": ["78", "77"]
41+
"versions": ["latest", "latest-1"]
4242
},
4343
{
4444
"browser": "firefox",
4545
"os": "OS X Catalina",
46-
"versions": ["74", "75"]
46+
"versions": ["latest", "latest-1"]
4747
},
4848
{
4949
"browser": "edge",
5050
"os": "OS X Catalina",
51-
"versions": ["80", "81"]
51+
"versions": ["latest", "latest-1"]
5252
}
5353
],
5454
"run_settings": {

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
},
1414
"dependencies": {
1515
"archiver": "^3.1.1",
16+
"chalk": "^4.1.0",
1617
"fs-extra": "^8.1.0",
1718
"mkdirp": "^1.0.3",
1819
"request": "^2.88.0",
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
'use strict';
2+
const chai = require("chai"),
3+
expect = chai.expect,
4+
chaiAsPromised = require("chai-as-promised");
5+
6+
chai.use(chaiAsPromised);
7+
const specDetails = require('../../../../../bin/helpers/sync/failedSpecsDetails');
8+
9+
describe("failedSpecsDetails", () => {
10+
context("data is empty", () => {
11+
let data = [];
12+
it('returns 0 exit code', () => {
13+
return specDetails.failedSpecsDetails(data).then((status) => {
14+
expect(status).to.equal(0);
15+
});
16+
});
17+
});
18+
19+
context("data does not have failed specs", () => {
20+
let data = [
21+
{specName: 'spec2.name.js', status: 'Skipped', combination: 'Win 10 / Chrome 78', sessionId: '3d3rdf3r...'}
22+
];
23+
24+
it("returns 0 exit code", () => {
25+
return specDetails.failedSpecsDetails(data).then((status) => {
26+
expect(status).to.equal(0);
27+
});
28+
});
29+
});
30+
31+
context("data has failed specs", () => {
32+
let data = [
33+
{specName: 'spec2.name.js', status: 'Failed', combination: 'Win 10 / Chrome 78', sessionId: '3d3rdf3r...'}
34+
];
35+
36+
it("returns 1 exit code", () => {
37+
return specDetails.failedSpecsDetails(data)
38+
.then((status) => {
39+
chai.assert.equal(status, 1);
40+
expect(status).to.equal(1);
41+
}).catch((status) => {
42+
expect(status).to.equal(1);
43+
});
44+
});
45+
});
46+
});

0 commit comments

Comments
 (0)