Skip to content

Commit f2acbe8

Browse files
authored
Merge branch 'master' into CYP-912-IP-Geolocation
2 parents 4075d36 + e3a0d0c commit f2acbe8

File tree

11 files changed

+292
-15
lines changed

11 files changed

+292
-15
lines changed

bin/commands/runs.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,18 @@ module.exports = function run(args, rawArgs) {
204204
build_id: data.build_id,
205205
test_zip_size: test_zip_size,
206206
npm_zip_size: npm_zip_size,
207+
test_suite_zip_upload: md5data.zipUrlPresent ? 0 : 1,
208+
package_zip_upload: md5data.packageUrlPresent ? 0 : 1
209+
};
210+
211+
if (!md5data.zipUrlPresent && zip.tests_upload_time) {
212+
dataToSend.test_suite_zip_size = parseFloat((test_zip_size / 1024).toFixed(2));
213+
dataToSend.test_suite_zip_upload_avg_speed = parseFloat(((test_zip_size * 1000) / (1024 * zip.tests_upload_time)).toFixed(2));
214+
};
215+
216+
if (!md5data.packageUrlPresent && zip.npm_package_upload_time) {
217+
dataToSend.npm_package_zip_size = parseFloat((npm_zip_size / 1024).toFixed(2));
218+
dataToSend.npm_package_zip_upload_avg_speed = parseFloat(((npm_zip_size * 1000) / (1024 * zip.npm_package_upload_time)).toFixed(2));
207219
};
208220

209221
if (zip.tests_upload_time || zip.npm_package_upload_time) {

bin/helpers/archiver.js

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
'use strict';
2-
const fs = require("fs");
2+
const fs = require("fs"),
3+
path = require("path");
34

45
const archiver = require("archiver"),
56
Constants = require('../helpers/constants'),
67
logger = require("./logger").winstonLogger,
7-
utils = require('../helpers/utils'),
8-
path = require('path');
8+
utils = require('../helpers/utils');
99

1010
const archiveSpecs = (runSettings, filePath, excludeFiles, md5data) => {
1111
return new Promise(function (resolve, reject) {
@@ -14,7 +14,17 @@ const archiveSpecs = (runSettings, filePath, excludeFiles, md5data) => {
1414
}
1515
var output = fs.createWriteStream(filePath);
1616

17-
var cypressFolderPath = path.dirname(runSettings.cypressConfigFilePath);
17+
var cypressFolderPath = '';
18+
let cypressAppendFilesZipLocation = '';
19+
if (runSettings.home_directory) {
20+
cypressFolderPath = runSettings.home_directory;
21+
cypressAppendFilesZipLocation = runSettings.cypressZipStartLocation;
22+
if (cypressAppendFilesZipLocation !== '') {
23+
cypressAppendFilesZipLocation += '/';
24+
}
25+
} else {
26+
cypressFolderPath = path.dirname(runSettings.cypressConfigFilePath);
27+
}
1828

1929
logger.info(`Creating tests.zip with files in ${cypressFolderPath}`);
2030

@@ -61,7 +71,7 @@ const archiveSpecs = (runSettings, filePath, excludeFiles, md5data) => {
6171

6272
if (Object.keys(packageJSON).length > 0) {
6373
let packageJSONString = JSON.stringify(packageJSON, null, 4);
64-
archive.append(packageJSONString, {name: 'browserstack-package.json'});
74+
archive.append(packageJSONString, {name: `${cypressAppendFilesZipLocation}browserstack-package.json`});
6575
}
6676

6777
// do not add cypress.json if arg provided is false
@@ -73,7 +83,7 @@ const archiveSpecs = (runSettings, filePath, excludeFiles, md5data) => {
7383
fs.readFileSync(runSettings.cypressConfigFilePath)
7484
);
7585
let cypressJSONString = JSON.stringify(cypressJSON, null, 4);
76-
archive.append(cypressJSONString, {name: 'cypress.json'});
86+
archive.append(cypressJSONString, {name: `${cypressAppendFilesZipLocation}cypress.json`});
7787
}
7888

7989
archive.finalize();

bin/helpers/capabilityHelper.js

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
const fs = require('fs'),
2+
path = require('path');
3+
14
const logger = require("./logger").winstonLogger,
25
Constants = require("./constants"),
3-
Utils = require("./utils"),
4-
fs = require('fs');
6+
Utils = require("./utils");
57

68
const caps = (bsConfig, zip) => {
79
return new Promise(function (resolve, reject) {
@@ -23,7 +25,7 @@ const caps = (bsConfig, zip) => {
2325
if (bsConfig.browsers) {
2426
bsConfig.browsers.forEach((element) => {
2527
osBrowser = element.os + "-" + element.browser;
26-
osAndBrowser = element.os + " / " + Utils.capitalizeFirstLetter(element.browser);
28+
osAndBrowser = (element.os) ? element.os : "Any OS" + " / " + Utils.capitalizeFirstLetter(element.browser);
2729
element.versions.forEach((version) => {
2830
osBrowserArray.push(osBrowser + version);
2931
browsersList.push(`${osAndBrowser} (${version})`);
@@ -129,6 +131,13 @@ const caps = (bsConfig, zip) => {
129131
})
130132
}
131133

134+
const addCypressZipStartLocation = (runSettings) => {
135+
let resolvedHomeDirectoryPath = path.resolve(runSettings.home_directory);
136+
let resolvedCypressConfigFilePath = path.resolve(runSettings.cypressConfigFilePath);
137+
runSettings.cypressZipStartLocation = path.dirname(resolvedCypressConfigFilePath.split(resolvedHomeDirectoryPath)[1]);
138+
runSettings.cypressZipStartLocation = runSettings.cypressZipStartLocation.substring(1);
139+
}
140+
132141
const validate = (bsConfig, args) => {
133142
return new Promise(function (resolve, reject) {
134143
logger.info(Constants.userMessages.VALIDATING_CONFIG);
@@ -189,11 +198,33 @@ const validate = (bsConfig, args) => {
189198
} catch(error){
190199
reject(Constants.validationMessages.INVALID_CYPRESS_JSON)
191200
}
201+
202+
//check if home_directory is present or not in user run_settings
203+
if (!Utils.isUndefined(bsConfig.run_settings.home_directory)) {
204+
// check if home_directory exists or not
205+
if (!fs.existsSync(bsConfig.run_settings.home_directory)) {
206+
reject(Constants.validationMessages.HOME_DIRECTORY_NOT_FOUND);
207+
}
208+
209+
// check if home_directory is a directory or not
210+
if (!fs.statSync(bsConfig.run_settings.home_directory).isDirectory()) {
211+
reject(Constants.validationMessages.HOME_DIRECTORY_NOT_A_DIRECTORY);
212+
}
213+
214+
// check if cypress config file (cypress.json) is a part of home_directory or not
215+
if (!path.resolve(bsConfig.run_settings.cypressConfigFilePath).includes(path.resolve(bsConfig.run_settings.home_directory))) {
216+
reject(Constants.validationMessages.CYPRESS_CONFIG_FILE_NOT_PART_OF_HOME_DIRECTORY);
217+
}
218+
219+
addCypressZipStartLocation(bsConfig.run_settings);
220+
}
221+
192222
resolve(cypressJson);
193223
});
194224
}
195225

196226
module.exports = {
197227
caps,
228+
addCypressZipStartLocation,
198229
validate
199230
}

bin/helpers/checkUploaded.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,12 @@ const checkSpecsMd5 = (runSettings, args, instrumentBlocks) => {
1515
if (args["force-upload"]) {
1616
return resolve("force-upload");
1717
}
18-
let cypressFolderPath = path.dirname(runSettings.cypressConfigFilePath);
18+
let cypressFolderPath = undefined;
19+
if (runSettings.home_directory) {
20+
cypressFolderPath = runSettings.home_directory;
21+
} else {
22+
cypressFolderPath = path.dirname(runSettings.cypressConfigFilePath);
23+
}
1924
let ignoreFiles = utils.getFilesToIgnore(runSettings, args.exclude, false);
2025
let options = {
2126
cwd: cypressFolderPath,
@@ -145,7 +150,8 @@ const checkUploadedMd5 = (bsConfig, args, instrumentBlocks) => {
145150
}
146151
});
147152
}).catch((err) => {
148-
resolve({zipUrlPresent: false, packageUrlPresent: false, error: err.stack.substring(0,100)});
153+
let errString = err.stack ? err.stack.toString().substring(0,100) : err.toString().substring(0,100);
154+
resolve({zipUrlPresent: false, packageUrlPresent: false, error: errString});
149155
});
150156
});
151157
};

bin/helpers/constants.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,10 @@ const validationMessages = {
9191
NOT_SUPPORTED_GEO_LOCATION: "The country code you have passed for IP Geolocation is currently not supported. Please refer the link https://www.browserstack.com/ip-geolocation for a list of supported countries.",
9292
NOT_AVAILABLE_GEO_LOCATION: "The country code you have passed for IP Geolocation is not available at the moment. Please try again in a few hours.",
9393
ACCESS_DENIED_GEO_LOCATION: "'geolocation' (IP Geolocation feature) capability is not supported in your account. It is only available under Enterprise plans, refer https://www.browserstack.com/ip-geolocation for more details.",
94-
NOT_ALLOWED_GEO_LOCATION_AND_LOCAL_MODE: "IP Geolocation feature is not available in conjunction with BrowserStack Local."
94+
NOT_ALLOWED_GEO_LOCATION_AND_LOCAL_MODE: "IP Geolocation feature is not available in conjunction with BrowserStack Local.",
95+
HOME_DIRECTORY_NOT_FOUND: "Specified home directory could not be found. Please make sure the path of the home directory is correct.",
96+
HOME_DIRECTORY_NOT_A_DIRECTORY: "Specified home directory is not a directory. The home directory can only be a directory and not a file.",
97+
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."
9598
};
9699

97100
const cliMessages = {

bin/helpers/packageInstaller.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ const packageWrapper = (bsConfig, packageDir, packageFile, md5data, instrumentBl
125125
Object.assign(obj, { packageArchieveCreated: true });
126126
return resolve(obj);
127127
}).catch((err) => {
128-
obj.error = err.stack.substring(0,100);
128+
obj.error = err.stack ? err.stack.toString().substring(0,100) : err.toString().substring(0,100);
129129
return resolve(obj);
130130
})
131131
})

bin/helpers/usageReporting.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,19 @@ function send(args) {
191191

192192
delete args.bstack_config;
193193

194+
let zipUploadDetails = {
195+
test_suite_zip_upload: data.test_suite_zip_upload,
196+
package_zip_upload: data.package_zip_upload,
197+
test_suite_zip_size: data.test_suite_zip_size,
198+
test_suite_zip_upload_avg_speed: data.test_suite_zip_upload_avg_speed,
199+
npm_package_zip_size: data.npm_package_zip_size,
200+
npm_package_zip_upload_avg_speed: data.npm_package_zip_upload_avg_speed,
201+
}
202+
203+
Object.keys(zipUploadDetails).forEach((key) => {
204+
delete data[key];
205+
})
206+
194207
const payload = {
195208
event_type: "cypress_cli_stats",
196209
data: {
@@ -211,6 +224,7 @@ function send(args) {
211224
event_timestamp: new Date().toLocaleString(),
212225
data: JSON.stringify(data),
213226
raw_args: JSON.stringify(args.raw_args),
227+
...zipUploadDetails,
214228
...args,
215229
},
216230
};

bin/helpers/utils.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,15 @@ exports.getErrorCodeFromMsg = (errMsg) => {
9191
case Constants.validationMessages.NOT_ALLOWED_GEO_LOCATION_AND_LOCAL_MODE:
9292
errorCode = 'not_allowed_geo_location_and_local_mode';
9393
break;
94+
case Constants.validationMessages.HOME_DIRECTORY_NOT_FOUND:
95+
errorCode = 'home_directory_not_found';
96+
break;
97+
case Constants.validationMessages.HOME_DIRECTORY_NOT_A_DIRECTORY:
98+
errorCode = 'home_directory_not_a_directory';
99+
break;
100+
case Constants.validationMessages.CYPRESS_CONFIG_FILE_NOT_PART_OF_HOME_DIRECTORY:
101+
errorCode = 'cypress_config_file_not_part_of_home_directory';
102+
break;
94103
}
95104
if (
96105
errMsg.includes("Please use --config-file <path to browserstack.json>.")
@@ -919,7 +928,7 @@ exports.setBrowsers = async (bsConfig, args) => {
919928
browsersList.forEach((browser)=>{
920929
let browserHash = {}
921930
let osBrowserDetails = browser.split(':')
922-
browserHash['os'] = osBrowserDetails[1].trim()
931+
if (!this.isUndefined(osBrowserDetails[1])) browserHash['os'] = osBrowserDetails[1].trim()
923932
let browserDetails = osBrowserDetails[0].split('@')
924933
browserHash['browser'] = browserDetails[0].trim()
925934
browserHash['versions'] = []

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "browserstack-cypress-cli",
3-
"version": "1.11.0",
3+
"version": "1.11.1",
44
"description": "BrowserStack Cypress CLI for Cypress integration with BrowserStack's remote devices.",
55
"main": "index.js",
66
"scripts": {

test/unit/bin/helpers/capabilityHelper.js

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,17 @@ describe("capabilityHelper.js", () => {
554554
});
555555
});
556556

557+
describe("addCypressZipStartLocation", () => {
558+
it("returns correct zip start location", () => {
559+
let runSettings = {
560+
home_directory: "/some/path",
561+
cypressConfigFilePath: "/some/path/that/is/nested/file.json"
562+
};
563+
capabilityHelper.addCypressZipStartLocation(runSettings);
564+
chai.assert.equal(runSettings.cypressZipStartLocation, "that/is/nested");
565+
});
566+
});
567+
557568
describe("validate", () => {
558569

559570
describe("validate parallels specified in bsconfig and arguments", () => {
@@ -1053,7 +1064,117 @@ describe("capabilityHelper.js", () => {
10531064
})
10541065
});
10551066
});
1067+
1068+
describe("validate home directory", () => {
1069+
beforeEach(() => {
1070+
bsConfig = {
1071+
auth: {},
1072+
browsers: [
1073+
{
1074+
browser: "chrome",
1075+
os: "Windows 10",
1076+
versions: ["78", "77"],
1077+
},
1078+
],
1079+
run_settings: {
1080+
cypress_proj_dir: "random path",
1081+
cypressConfigFilePath: "random path",
1082+
cypressProjectDir: "random path"
1083+
},
1084+
};
1085+
});
10561086

1087+
it("does not exist", () => {
1088+
bsConfig.run_settings.cypressConfigFilePath = 'false';
1089+
bsConfig.run_settings.cypress_config_filename = 'false';
1090+
bsConfig.run_settings.home_directory = '/some/random';
1091+
1092+
sinon.stub(fs, 'existsSync').returns(false);
1093+
fs.existsSync.restore();
1094+
1095+
return capabilityHelper
1096+
.validate(bsConfig, {})
1097+
.then(function (data) {
1098+
chai.assert.fail("Promise error");
1099+
})
1100+
.catch((error) => {
1101+
chai.assert.equal(
1102+
error,
1103+
Constants.validationMessages.HOME_DIRECTORY_NOT_FOUND
1104+
);
1105+
});
1106+
});
1107+
1108+
it("is not a directory", () => {
1109+
bsConfig.run_settings.cypressConfigFilePath = 'false';
1110+
bsConfig.run_settings.cypress_config_filename = 'false';
1111+
bsConfig.run_settings.home_directory = '/some/random/file.ext';
1112+
1113+
sinon.stub(fs, 'existsSync').returns(true);
1114+
sinon.stub(fs, 'statSync').returns({ isDirectory: () => false });
1115+
1116+
return capabilityHelper
1117+
.validate(bsConfig, {})
1118+
.then(function (data) {
1119+
chai.assert.fail("Promise error");
1120+
})
1121+
.catch((error) => {
1122+
chai.assert.equal(
1123+
error,
1124+
Constants.validationMessages.HOME_DIRECTORY_NOT_A_DIRECTORY
1125+
);
1126+
fs.existsSync.restore();
1127+
fs.statSync.restore();
1128+
});
1129+
});
1130+
1131+
it("does not contain cypressConfigFilePath", () => {
1132+
bsConfig.run_settings.cypressConfigFilePath = 'false';
1133+
bsConfig.run_settings.cypress_config_filename = 'false';
1134+
bsConfig.run_settings.home_directory = '/some/random';
1135+
1136+
sinon.stub(fs, 'existsSync').returns(true);
1137+
sinon.stub(fs, 'statSync').returns({ isDirectory: () => true });
1138+
1139+
return capabilityHelper
1140+
.validate(bsConfig, {})
1141+
.then(function (data) {
1142+
chai.assert.fail("Promise error");
1143+
})
1144+
.catch((error) => {
1145+
chai.assert.equal(
1146+
error,
1147+
Constants.validationMessages.CYPRESS_CONFIG_FILE_NOT_PART_OF_HOME_DIRECTORY
1148+
);
1149+
fs.existsSync.restore();
1150+
fs.statSync.restore();
1151+
});
1152+
});
1153+
1154+
it("does not contain cypressConfigFilePath with special chars", () => {
1155+
bsConfig.run_settings.cypressConfigFilePath = 'false';
1156+
bsConfig.run_settings.cypress_config_filename = 'false';
1157+
bsConfig.run_settings.home_directory = '/$some!@#$%^&*()_+=-[]{};:<>?\'\\\//random';
1158+
1159+
sinon.stub(fs, 'existsSync').returns(true);
1160+
sinon.stub(fs, 'statSync').returns({ isDirectory: () => true });
1161+
1162+
return capabilityHelper
1163+
.validate(bsConfig, {})
1164+
.then(function (data) {
1165+
chai.assert.fail("Promise error");
1166+
})
1167+
.catch((error) => {
1168+
chai.assert.equal(
1169+
error,
1170+
Constants.validationMessages.CYPRESS_CONFIG_FILE_NOT_PART_OF_HOME_DIRECTORY
1171+
);
1172+
fs.existsSync.restore();
1173+
fs.statSync.restore();
1174+
});
1175+
});
1176+
});
1177+
10571178
describe("validate ip geolocation", () => {
10581179
beforeEach(() => {
10591180
bsConfig = {
@@ -1146,5 +1267,6 @@ describe("capabilityHelper.js", () => {
11461267
});
11471268
});
11481269
});
1270+
11491271
});
11501272
});

0 commit comments

Comments
 (0)