Skip to content

Changes for enforce_settings to enforce run_settings over cypress conf #741

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Dec 8, 2023
10 changes: 9 additions & 1 deletion bin/commands/runs.js
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ module.exports = function run(args, rawArgs) {
let specFiles = utils.getNumberOfSpecFiles(bsConfig, args, cypressConfigFile);
markBlockEnd('getNumberOfSpecFiles');

bsConfig['run_settings']['video_config'] = utils.getVideoConfig(cypressConfigFile);
bsConfig['run_settings']['video_config'] = utils.getVideoConfig(cypressConfigFile, bsConfig);

// return the number of parallels user specified
let userSpecifiedParallels = utils.getParallels(bsConfig, args);
Expand Down Expand Up @@ -251,6 +251,14 @@ module.exports = function run(args, rawArgs) {
if (process.env.BROWSERSTACK_TEST_ACCESSIBILITY === 'true') {
supportFileCleanup();
}
// Set config args for enforce_settings
if ( !utils.isUndefinedOrFalse(bsConfig.run_settings.enforce_settings) ) {
markBlockStart('setEnforceSettingsConfig');
logger.debug('Started setting the configs');
utils.setEnforceSettingsConfig(bsConfig);
logger.debug('Completed setting the configs');
markBlockEnd('setEnforceSettingsConfig');
}
// Create build
//setup Local Testing
markBlockStart('localSetup');
Expand Down
12 changes: 11 additions & 1 deletion bin/helpers/capabilityHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,10 @@ const validate = (bsConfig, args) => {
reject(Constants.validationMessages.EMPTY_CYPRESS_CONFIG_FILE);
}

if ( bsConfig && bsConfig.run_settings && bsConfig.run_settings.enforce_settings && bsConfig.run_settings.enforce_settings.toString() === 'true' && Utils.isUndefined(bsConfig.run_settings.specs) ) {
reject(Constants.validationMessages.EMPTY_SPECS_IN_BROWSERSTACK_JSON);
}

// 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);

Expand Down Expand Up @@ -214,7 +218,8 @@ const validate = (bsConfig, args) => {

logger.debug(`Validating ${bsConfig.run_settings.cypress_config_filename}`);
try {
if (bsConfig.run_settings.cypress_config_filename !== 'false') {
// Not reading cypress config file upon enforce_settings
if (Utils.isUndefinedOrFalse(bsConfig.run_settings.enforce_settings) && bsConfig.run_settings.cypress_config_filename !== 'false') {
if (bsConfig.run_settings.cypressTestSuiteType === Constants.CYPRESS_V10_AND_ABOVE_TYPE) {
const completeCypressConfigFile = readCypressConfigFile(bsConfig)
if (!Utils.isUndefined(completeCypressConfigFile)) {
Expand All @@ -234,6 +239,11 @@ const validate = (bsConfig, args) => {
// Detect if the user is not using the right directory structure, and throw an error
if (!Utils.isUndefined(cypressConfigFile.integrationFolder) && !Utils.isCypressProjDirValid(bsConfig.run_settings.cypressProjectDir,cypressConfigFile.integrationFolder)) reject(Constants.validationMessages.INCORRECT_DIRECTORY_STRUCTURE);
}
else {
logger.debug("Validating baseurl and integrationFolder in browserstack.json");
if (!Utils.isUndefined(bsConfig.run_settings.baseUrl) && bsConfig.run_settings.baseUrl.includes("localhost") && !Utils.getLocalFlag(bsConfig.connection_settings)) reject(Constants.validationMessages.LOCAL_NOT_SET.replace("<baseUrlValue>", bsConfig.run_settings.baseUrl));
if (!Utils.isUndefined(bsConfig.run_settings.integrationFolder) && !Utils.isCypressProjDirValid(bsConfig.run_settings.cypressProjectDir,bsConfig.run_settings.integrationFolder)) reject(Constants.validationMessages.INCORRECT_DIRECTORY_STRUCTURE);
}
} catch(error){
reject(Constants.validationMessages.INVALID_CYPRESS_JSON)
}
Expand Down
4 changes: 4 additions & 0 deletions bin/helpers/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ const userMessages = {
UPLOADING_NPM_PACKAGES_SUCCESS: "Uploaded node_modules successfully",
SKIP_UPLOADING_TESTS:
"Skipping zip upload since BrowserStack already has your test suite that has not changed since the last run.",
SKIP_NPM_INSTALL:
"Skipping NPM Install as the enforce_settings has been passed.",
SKIP_UPLOADING_NPM_PACKAGES:
"Skipping the upload of node_modules since BrowserStack has already cached your npm dependencies that have not changed since the last run.",
LOCAL_TRUE: "you will now be able to test localhost / private URLs",
Expand Down Expand Up @@ -134,6 +136,8 @@ const validationMessages = {
"cypress_proj_dir is not set in run_settings. See https://www.browserstack.com/docs/automate/cypress/sample-tutorial to learn more.",
EMPTY_CYPRESS_CONFIG_FILE:
"cypress_config_file is not set in run_settings. See https://www.browserstack.com/docs/automate/cypress/configuration-file to learn more.",
EMPTY_SPECS_IN_BROWSERSTACK_JSON:
"specs is required when enforce_settings is true in run_settings of browserstack.json",
VALIDATED: "browserstack.json file is validated",
NOT_VALID: "browerstack.json is not valid",
NOT_VALID_JSON: "browerstack.json is not a valid json",
Expand Down
6 changes: 5 additions & 1 deletion bin/helpers/packageInstaller.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,11 @@ const packageSetupAndInstaller = (bsConfig, packageDir, instrumentBlocks) => {
let obj = {
packagesInstalled: false
};

if (bsConfig && bsConfig.run_settings && bsConfig.run_settings.enforce_settings && bsConfig.run_settings.enforce_settings.toString() === 'true' ) {
logger.info("Enforce_settings is enabled in run_settings");
logger.debug(Constants.userMessages.SKIP_NPM_INSTALL);
return resolve(obj);
}
logger.info(Constants.userMessages.NPM_INSTALL);
instrumentBlocks.markBlockStart("packageInstaller.folderSetup");
logger.debug("Started setting up package folder");
Expand Down
67 changes: 62 additions & 5 deletions bin/helpers/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,8 @@ exports.setProjectId = (bsConfig, args, cypressConfigFile) => {
} else if(!this.isUndefined(bsConfig.run_settings["projectId"])) {
return bsConfig.run_settings["projectId"];
} else {
if (!this.isUndefined(cypressConfigFile) && !this.isUndefined(cypressConfigFile["projectId"])) {
// ignore reading cypressconfig if enforce_settings is passed
if (this.isUndefinedOrFalse(bsConfig.run_settings.enforce_settings) && !this.isUndefined(cypressConfigFile) && !this.isUndefined(cypressConfigFile["projectId"])) {
return cypressConfigFile["projectId"];
}
}
Expand Down Expand Up @@ -628,6 +629,8 @@ exports.isPositiveInteger = (str) => {

exports.isTrueString = value => (!this.isUndefined(value) && value.toString().toLowerCase() === 'true');

exports.isUndefinedOrFalse = value => ( this.isUndefined(value) || value.toString().toLowerCase() === 'false');

exports.isFloat = (value) => Number(value) && Number(value) % 1 !== 0;

exports.isInteger = (value) => Number.isInteger(value);
Expand Down Expand Up @@ -1077,7 +1080,8 @@ exports.getNumberOfSpecFiles = (bsConfig, args, cypressConfig) => {
if (bsConfig.run_settings.cypressTestSuiteType === Constants.CYPRESS_V10_AND_ABOVE_TYPE) {
defaultSpecFolder = Constants.DEFAULT_CYPRESS_10_SPEC_PATH
testFolderPath = defaultSpecFolder
if(!this.isUndefined(cypressConfig) && !this.isUndefined(cypressConfig.e2e)) {
// Read cypress config if enforce_settings is not present
if(this.isUndefinedOrFalse(bsConfig.run_settings.enforce_settings) && !this.isUndefined(cypressConfig) && !this.isUndefined(cypressConfig.e2e)) {
if(!this.isUndefined(cypressConfig.e2e.specPattern)) {
globCypressConfigSpecPatterns = Array.isArray(cypressConfig.e2e.specPattern) ?
cypressConfig.e2e.specPattern : [cypressConfig.e2e.specPattern];
Expand Down Expand Up @@ -1286,6 +1290,50 @@ exports.setConfig = (bsConfig, args) => {
}
}

exports.setVideoCliConfig = (bsConfig, videoConfig) => {
// set cli config for video for cypress 13 and above to attain default value of true.
if(this.isUndefined(videoConfig) || this.isUndefined(videoConfig.video) || this.isUndefined(videoConfig.videoUploadOnPasses) || this.isUndefined(bsConfig)) return;
let user_cypress_version = (bsConfig && bsConfig.run_settings && bsConfig.run_settings.cypress_version) ? bsConfig.run_settings.cypress_version.toString() : undefined;
let cypress_major_version = (user_cypress_version && user_cypress_version.match(/^(\d+)/)) ? user_cypress_version.split(".")[0] : undefined;
let config_args = (bsConfig && bsConfig.run_settings && bsConfig.run_settings.config) ? bsConfig.run_settings.config : undefined;
if(this.isUndefined(user_cypress_version) || this.isUndefined(cypress_major_version) || parseInt(cypress_major_version) >= 13 ) {
let video_args = `video=${videoConfig.video},videoUploadOnPasses=${videoConfig.videoUploadOnPasses}`;
config_args = this.isUndefined(config_args) ? video_args : config_args + ',' + video_args;
logger.debug(`Setting default video true for cypress 13 and above in cli for cypress version ${user_cypress_version} with cli args - ${config_args}`)
}
if (bsConfig.run_settings && this.isNotUndefined(config_args)) bsConfig["run_settings"]["config"] = config_args;
}

// set configs if enforce_settings is passed
exports.setEnforceSettingsConfig = (bsConfig) => {
if ( this.isUndefined(bsConfig) || this.isUndefined(bsConfig.run_settings) ) return;
let config_args = (bsConfig && bsConfig.run_settings && bsConfig.run_settings.config) ? bsConfig.run_settings.config : undefined;
if ( this.isUndefined(config_args) || !config_args.includes("video") ) {
let video_args = (this.isUndefined(bsConfig.run_settings.video_config) || this.isUndefined(bsConfig.run_settings.video_config.video) || !bsConfig.run_settings.video_config.video ) ? 'video=false' : 'video=true' ;
video_args += (this.isUndefined(bsConfig.run_settings.video_config) || this.isUndefined(bsConfig.run_settings.video_config.videoUploadOnPasses) || !bsConfig.run_settings.video_config.videoUploadOnPasses ) ? ',videoUploadOnPasses=false' : ',videoUploadOnPasses=true';
config_args = this.isUndefined(config_args) ? video_args : config_args + ',' + video_args;
logger.debug(`Setting video_args for enforce_settings to ${video_args}`);
}
if ( (bsConfig && bsConfig.run_settings && bsConfig.run_settings.baseUrl) && (this.isUndefined(config_args) || !config_args.includes("baseUrl")) ) {
let base_url_args = 'baseUrl='+bsConfig.run_settings.baseUrl;
config_args = this.isUndefined(config_args) ? base_url_args : config_args + ',' + base_url_args;
logger.debug(`Setting base_url_args for enforce_settings to ${base_url_args}`);
}
// set specs in config of specpattern to override cypress config
if( this.isNotUndefined(bsConfig.run_settings.specs) && bsConfig.run_settings.cypressTestSuiteType === Constants.CYPRESS_V10_AND_ABOVE_TYPE && (this.isUndefined(config_args) || !config_args.includes("specPattern")) ) {
// doing this only for cypress 10 and above as --spec is given precedence for cypress 9.
let specConfigs = bsConfig.run_settings.specs;
// if multiple specs are passed, convert it into an array.
if(specConfigs && specConfigs.includes(',')) {
specConfigs = JSON.stringify(specConfigs.split(','));
}
let spec_pattern_args = 'specPattern="'+specConfigs+'"';
config_args = this.isUndefined(config_args) ? spec_pattern_args : config_args + ',' + spec_pattern_args;
}
if ( this.isNotUndefined(config_args) ) bsConfig["run_settings"]["config"] = config_args;
logger.debug(`Setting conifg_args for enforce_settings to ${config_args}`);
}

// blindly send other passed configs with run_settings and handle at backend
exports.setOtherConfigs = (bsConfig, args) => {
if(o11yHelpers.isTestObservabilitySession() && process.env.BS_TESTOPS_JWT) {
Expand Down Expand Up @@ -1522,14 +1570,23 @@ exports.fetchFolderSize = async (dir) => {
}
}

exports.getVideoConfig = (cypressConfig) => {
exports.getVideoConfig = (cypressConfig, bsConfig = {}) => {
let conf = {
video: true,
videoUploadOnPasses: true
}
if (!this.isUndefined(cypressConfig.video)) conf.video = cypressConfig.video;
if (!this.isUndefined(cypressConfig.videoUploadOnPasses)) conf.videoUploadOnPasses = cypressConfig.videoUploadOnPasses;
// Reading bsconfig in case of enforce_settings
if ( this.isUndefined(bsConfig.run_settings) || this.isUndefinedOrFalse(bsConfig.run_settings.enforce_settings) ) {
if (!this.isUndefined(cypressConfig.video)) conf.video = cypressConfig.video;
if (!this.isUndefined(cypressConfig.videoUploadOnPasses)) conf.videoUploadOnPasses = cypressConfig.videoUploadOnPasses;
}
else {
if (!this.isUndefined(bsConfig.run_settings) && !this.isUndefined(bsConfig.run_settings.video)) conf.video = bsConfig.run_settings.video;
if (!this.isUndefined(bsConfig.run_settings) && !this.isUndefined(bsConfig.run_settings.videoUploadOnPasses)) conf.videoUploadOnPasses = bsConfig.run_settings.videoUploadOnPasses;
}

// set video in cli config in case of cypress 13 or above as default value is false there.
this.setVideoCliConfig(bsConfig,conf);
logger.debug(`Setting video = ${conf.video}`);
logger.debug(`Setting videoUploadOnPasses = ${conf.videoUploadOnPasses}`);
return conf;
Expand Down
Loading