Skip to content

Commit

Permalink
Merge branch 'master' into HST-000-add-undefined-check
Browse files Browse the repository at this point in the history
  • Loading branch information
pranavj1001 authored Apr 24, 2024
2 parents 5924cd4 + 2c1dce2 commit 75f0b34
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 18 deletions.
2 changes: 1 addition & 1 deletion bin/commands/runs.js
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ module.exports = function run(args, rawArgs) {
if ( !utils.isUndefinedOrFalse(bsConfig.run_settings.enforce_settings) ) {
markBlockStart('setEnforceSettingsConfig');
logger.debug('Started setting the configs');
utils.setEnforceSettingsConfig(bsConfig);
utils.setEnforceSettingsConfig(bsConfig, args);
logger.debug('Completed setting the configs');
markBlockEnd('setEnforceSettingsConfig');
}
Expand Down
1 change: 1 addition & 0 deletions bin/helpers/atsHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ exports.patchCypressConfigFileContent = (bsConfig) => {
if (originalFunction !== null && originalFunction !== undefined) {
originalFunction(bstackOn, config);
}
return config;
}
`

Expand Down
82 changes: 76 additions & 6 deletions bin/helpers/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -1163,7 +1163,7 @@ exports.getNumberOfSpecFiles = (bsConfig, args, cypressConfig, turboScaleSession
};

exports.sanitizeSpecsPattern = (pattern) => {
return pattern && pattern.split(",").length > 1 ? "{" + pattern + "}" : pattern;
return pattern && !(pattern.includes("{") && pattern.includes("}")) && pattern.split(",").length > 1 ? "{" + pattern + "}" : pattern;
}

exports.generateUniqueHash = () => {
Expand Down Expand Up @@ -1319,7 +1319,7 @@ exports.setVideoCliConfig = (bsConfig, videoConfig) => {
}

// set configs if enforce_settings is passed
exports.setEnforceSettingsConfig = (bsConfig) => {
exports.setEnforceSettingsConfig = (bsConfig, args) => {
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") ) {
Expand All @@ -1337,17 +1337,87 @@ exports.setEnforceSettingsConfig = (bsConfig) => {
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 = "";

if (specConfigs && specConfigs.includes('{') && specConfigs.includes('}')) {
if (specConfigs && !Array.isArray(specConfigs)) {
if (specConfigs.includes(',')) {
specConfigs = this.splitStringByCharButIgnoreIfWithinARange(specConfigs, ',', '{', '}');
} else {
specConfigs = [specConfigs];
}
}
let ignoreFiles = args.exclude || bsConfig.run_settings.exclude
let specFilesMatched = [];
specConfigs.forEach(specPattern => {
specFilesMatched.push(
...glob.sync(specPattern, {
cwd: bsConfig.run_settings.cypressProjectDir, matchBase: true, ignore: ignoreFiles
})
);
});
logger.debug(`${specFilesMatched && specFilesMatched.length > 0 ? specFilesMatched.length : 0} spec files found with the provided specPattern for enforce_settings`);
// If spec files were found then lets we'll load the matched spec files
// If spec files were not found then we'll let cypress decide the loading of spec files
spec_pattern_args = `specPattern=${JSON.stringify(specFilesMatched && specFilesMatched.length > 0 ? specFilesMatched : specConfigs)}`;
} else {
// if multiple specs are passed, convert it into an array.
if(specConfigs && specConfigs.includes(',')) {
specConfigs = JSON.stringify(specConfigs.split(','));
}
spec_pattern_args = `specPattern=${specConfigs}`;
}
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}`);
}

/**
* Splits a string by a specified splitChar.
* If leftLimiter and rightLimiter are specified then string won't be splitted if the splitChar is within the range
*
* @param {String} str - the string that needs to be splitted
* @param {String} splitChar - the split string/char from which the string will be splited
* @param {String} [leftLimiter] - the starting string/char of the range
* @param {String} [rightLimiter] - the ending string/char of the range
*
* @example Example usage of splitStringByCharButIgnoreIfWithinARange.
* // returns ["folder/A/B", "folder/{C,D}/E"]
* utils.splitStringByCharButIgnoreIfWithinARange("folder/A/B,folder/{C,D}/E", ",", "{", "}");
* @returns String[] | null
*/
exports.splitStringByCharButIgnoreIfWithinARange = (str, splitChar, leftLimiter, rightLimiter) => {
if (typeof(str) !== 'string' || this.isUndefined(splitChar)) return null;

if (this.isUndefined(leftLimiter) || this.isUndefined(rightLimiter)) return str.split(splitChar);

let result = [];
let buffer = '';
let openBraceCount = 0;

for (let i = 0; i < str.length; i++) {
if (str[i] === leftLimiter) {
openBraceCount++;
} else if (str[i] === rightLimiter) {
openBraceCount--;
}

if (str[i] === splitChar && openBraceCount === 0) {
result.push(buffer);
buffer = '';
} else {
buffer += str[i];
}
}

if (buffer !== '') {
result.push(buffer);
}

return result;
}

// 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
103 changes: 92 additions & 11 deletions test/unit/bin/helpers/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -2721,6 +2721,10 @@ describe('utils', () => {
expect(utils.sanitizeSpecsPattern('pattern3')).to.eq('pattern3');
});

it('should not wrap pattern around {} when input already has {}', () => {
expect(utils.sanitizeSpecsPattern('pattern/{folderA,folderB}/*.spec.ts')).to.eq('pattern/{folderA,folderB}/*.spec.ts');
});

it('should return undefined when --spec is undefined', () => {
expect(utils.sanitizeSpecsPattern(undefined)).to.eq(undefined);
});
Expand Down Expand Up @@ -3094,56 +3098,133 @@ describe('utils', () => {
describe('setEnforceSettingsConfig', () => {
it('the video config should be assigned to bsconfig run_settings config', () => {
let bsConfig = {
run_settings: { video_config: { video:true, videoUploadOnPasses:true} },
run_settings: {
video_config: { video:true, videoUploadOnPasses:true },
cypressProjectDir: 'cypressProjectDir',
},
};
let args = {
config: 'video=true,videoUploadOnPasses=true'
}
utils.setEnforceSettingsConfig(bsConfig);
utils.setEnforceSettingsConfig(bsConfig, args);
expect(args.config).to.be.eql(bsConfig.run_settings.config);
});
it('the specPattern config should be assigned as strings for single string to bsconfig run_settings config', () => {
it('the specPattern config should be assigned as array for single spec string to bsconfig run_settings config', () => {
let bsConfig = {
run_settings: { specs: 'somerandomspecs', cypressTestSuiteType: 'CYPRESS_V10_AND_ABOVE_TYPE' },
run_settings: {
specs: 'somerandomspecs',
cypressTestSuiteType: 'CYPRESS_V10_AND_ABOVE_TYPE',
cypressProjectDir: 'cypressProjectDir',
},
};
let args = {
exclude: "",
config: 'video=false,videoUploadOnPasses=false,specPattern=somerandomspecs'
}
utils.setEnforceSettingsConfig(bsConfig);
utils.setEnforceSettingsConfig(bsConfig, args);
expect(args.config).to.be.eql(bsConfig.run_settings.config);
});
it('the specPattern config should be assigned as array for multiple spec strings to bsconfig run_settings config', () => {
let bsConfig = {
run_settings: { specs: 'somerandomspecs1,somerandomspecs2', cypressTestSuiteType: 'CYPRESS_V10_AND_ABOVE_TYPE' },
run_settings: {
specs: 'somerandomspecs1,somerandomspecs2',
cypressTestSuiteType: 'CYPRESS_V10_AND_ABOVE_TYPE',
cypressProjectDir: 'cypressProjectDir',
},
};
let args = {
exclude: "",
config: 'video=false,videoUploadOnPasses=false,specPattern=["somerandomspecs1","somerandomspecs2"]'
}
utils.setEnforceSettingsConfig(bsConfig);
utils.setEnforceSettingsConfig(bsConfig, args);
expect(args.config).to.be.eql(bsConfig.run_settings.config);
});
it('the specPattern config should not be assigned just on the basis of "," as array for single spec string to bsconfig run_settings config', () => {
let bsConfig = {
run_settings: {
specs: 'folders/{sample1,sample2}/somerandomspecs',
cypressTestSuiteType: 'CYPRESS_V10_AND_ABOVE_TYPE',
cypressProjectDir: 'cypressProjectDir',
},
};
let args = {
exclude: "",
config: 'video=false,videoUploadOnPasses=false,specPattern=["folders/{sample1,sample2}/somerandomspecs"]'
}
utils.setEnforceSettingsConfig(bsConfig, args);
expect(args.config).to.be.eql(bsConfig.run_settings.config);
});
it('the specPattern config should not be assigned just on the basis of "," as array for multiple spec strings to bsconfig run_settings config', () => {
let bsConfig = {
run_settings: {
specs: 'folders/{sample1,sample2}/somerandomspecs,folders2/sample3/somerandomspecs2',
cypressTestSuiteType: 'CYPRESS_V10_AND_ABOVE_TYPE',
cypressProjectDir: 'cypressProjectDir',
},
};
let args = {
exclude: "",
config: 'video=false,videoUploadOnPasses=false,specPattern=["folders/{sample1,sample2}/somerandomspecs","folders2/sample3/somerandomspecs2"]'
}
utils.setEnforceSettingsConfig(bsConfig, args);
expect(args.config).to.be.eql(bsConfig.run_settings.config);
});
it('the testFiles config should be assigned to bsconfig run_settings config', () => {
let bsConfig = {
run_settings: { specs: 'somerandomspecs', cypressTestSuiteType: 'CYPRESS_V9_AND_OLDER_TYPE' },
};
let args = {
config: 'video=false,videoUploadOnPasses=false'
config: 'video=false,videoUploadOnPasses=false',
cypressProjectDir: 'cypressProjectDir',
}
utils.setEnforceSettingsConfig(bsConfig);
utils.setEnforceSettingsConfig(bsConfig, args);
expect(args.config).to.be.eql(bsConfig.run_settings.config);
});
it('the baseUrl config should be assigned to bsconfig run_settings config', () => {
let bsConfig = {
run_settings: { baseUrl: 'http://localhost:8080' },
run_settings: {
baseUrl: 'http://localhost:8080',
cypressProjectDir: 'cypressProjectDir',
},
};
let args = {
config: 'video=false,videoUploadOnPasses=false,baseUrl=http://localhost:8080'
}
utils.setEnforceSettingsConfig(bsConfig);
utils.setEnforceSettingsConfig(bsConfig, args);
expect(args.config).to.be.eql(bsConfig.run_settings.config);
});
});

describe('splitStringByCharButIgnoreIfWithinARange', () => {
it('should return null if string is not provided', () => {
expect(utils.splitStringByCharButIgnoreIfWithinARange()).to.be.eql(null);
});

it('should return null if splitChar is not provided', () => {
expect(utils.splitStringByCharButIgnoreIfWithinARange("some")).to.be.eql(null);
});

it('should return splitted string even if leftLimiter and rightLimiter is not provided', () => {
expect(utils.splitStringByCharButIgnoreIfWithinARange("some,random,text", ",")).to.be.eql(["some", "random", "text"]);
});

it('should return splitted string even if leftLimiter is provided but rightLimiter is not provided', () => {
expect(utils.splitStringByCharButIgnoreIfWithinARange("some,random,{text,here},and,here", ",", "{")).to.be.eql(["some", "random", "{text", "here}", "and", "here"]);
});

it('should return splitted string even if leftLimiter is not provided but rightLimiter is provided', () => {
expect(utils.splitStringByCharButIgnoreIfWithinARange("some,random,{text,here},and,here", ",", null, "}")).to.be.eql(["some", "random", "{text", "here}", "and", "here"]);
});

it('should return splitted string and ignore splitting if splitChar is withing the leftLimiter and rightLimiter', () => {
expect(utils.splitStringByCharButIgnoreIfWithinARange("some,random,{text,here},and,here", ",", "{", "}")).to.be.eql(["some", "random", "{text,here}", "and", "here"]);
});

it('should return splitted string and ignore splitting if splitChar is withing the leftLimiter and rightLimiter', () => {
expect(utils.splitStringByCharButIgnoreIfWithinARange("some,random,{text,here}", ",", "{", "}")).to.be.eql(["some", "random", "{text,here}"]);
});
});

describe('generateUniqueHash', () => {
beforeEach(() => {
let interfaceList = {
Expand Down

0 comments on commit 75f0b34

Please sign in to comment.