@opentext/sdp-sdm-tests-to-run-conversion
Version:
JavaScript-based tool that converts the testsToRun parameter for running automated tests from OpenText Core Software Delivery Platform and OpenText Software Delivery Management.
311 lines (269 loc) • 9.87 kB
text/typescript
/*
* Copyright 2016-2025 Open Text.
*
* The only warranties for products and services of Open Text and
* its affiliates and licensors (“Open Text”) are as may be set forth
* in the express warranty statements accompanying such products and services.
* Nothing herein should be construed as constituting an additional warranty.
* Open Text shall not be liable for technical or editorial errors or
* omissions contained herein. The information contained herein is subject
* to change without notice.
*
* Except as specifically indicated otherwise, this document contains
* confidential information and a valid license is required for possession,
* use or copying. If this work is provided to the U.S. Government,
* consistent with FAR 12.211 and 12.212, Commercial Computer Software,
* Computer Software Documentation, and Technical Data for Commercial Items are
* licensed to the U.S. Government under vendor's standard commercial license.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { js2xml } from "xml-js";
import { getConfig } from "./config/config";
import parseCustomFramework from "./customFrameworkParser";
import Framework from "./dto/Framework";
import Replacement from "./dto/Replacement";
import Test from "./dto/Test";
import Logger from "./utils/logger";
import UftTestParameter from "./dto/uft/UftTestParameter";
const LOGGER: Logger = new Logger("testsToRunConverter.ts");
const CUSTOM_FRAMEWORK_PACKAGE_PLACEHOLDER = "$package";
const CUSTOM_FRAMEWORK_CLASS_PLACEHOLDER = "$class";
const CUSTOM_FRAMEWORK_TEST_PLACEHOLDER = "$testName";
const convertTestsToRun = (testsToRun: Test[]): string => {
const framework = getConfig().framework;
if (!framework) {
throw Error("Could not get framework from config.");
}
switch (framework) {
case Framework.JUnit:
case Framework.MavenSurefire:
case Framework.TestNG:
return convertJUnitTestsToRun(testsToRun);
case Framework.Cucumber:
return convertCucumberTestsToRun(testsToRun);
case Framework.CucumberBDD:
return convertCucumberBDDTestsToRun(testsToRun);
case Framework.UFT:
return convertUftTestsToRun(testsToRun);
case Framework.Custom:
return convertCustomTestsToRun(testsToRun);
default:
throw Error(
`Unsupported framework: '${framework}'. See the list of available parameters at https://github.com/MicroFocus/sdp-sdm-tests-to-run-conversion?tab=readme-ov-file#412-parameters.`,
);
}
};
const convertJUnitTestsToRun = (testsToRun: Test[]): string => {
LOGGER.info(`Converting testsToRun to JUnit/Maven Surefire/TestNG format...`);
let convertedTestsMap: { [key: string]: string } = {};
testsToRun.forEach((testToRun) => {
const fullPath = testToRun.packageName
? testToRun.packageName + "." + testToRun.className
: testToRun.className;
if (convertedTestsMap[fullPath]) {
convertedTestsMap[fullPath] =
`${convertedTestsMap[fullPath]}+${testToRun.testName}`;
} else {
convertedTestsMap[fullPath] = testToRun.testName;
}
});
const convertedTestsToRun = Object.keys(convertedTestsMap)
.map((key) => key + "#" + convertedTestsMap[key])
.join(",");
LOGGER.debug(
`Successfully converted the tests to run: ${convertedTestsToRun}`,
);
return convertedTestsToRun;
};
const convertCucumberTestsToRun = (testsToRun: Test[]): string => {
LOGGER.info(`Converting testsToRun to Cucumber format...`);
const convertedTestsToRun = testsToRun
.filter(
(testToRun) =>
testToRun.parameters && testToRun.parameters["featureFilePath"],
)
.map(
(testToRun) => '\\"' + testToRun.parameters!["featureFilePath"] + '\\"',
)
.filter((value, index, array) => array.indexOf(value) === index)
.join(" ");
LOGGER.debug(
`Successfully converted the tests to run: ${convertedTestsToRun}`,
);
return convertedTestsToRun;
};
const convertCucumberBDDTestsToRun = (testsToRun: Test[]): string => {
LOGGER.info(`Converting testsToRun to Cucumber format...`);
const convertedFeatures = testsToRun
.filter(
(testToRun) =>
testToRun.parameters && testToRun.parameters["featureFilePath"],
)
.map((testToRun) => `'${testToRun.parameters!["featureFilePath"]}'`)
.filter((value, index, array) => array.indexOf(value) === index)
.join(" ");
const convertedTests = testsToRun
.map((testToRun) => testToRun.testName.replace("'", "."))
.map((testName) => `--name '^${testName}$'`)
.filter((value, index, array) => array.indexOf(value) === index)
.join(" ");
const convertedTestsToRun = `${convertedFeatures} ${convertedTests}`;
LOGGER.debug(
`Successfully converted the tests to run: ${convertedTestsToRun}`,
);
return convertedTestsToRun;
};
const convertUftTestsToRun = (testsToRun: Test[]): string => {
LOGGER.info(`Converting testsToRun to UFT One format...`);
const uftTestsToRun = testsToRun.map((testToRun) => {
let parameters: UftTestParameter[] = [];
if (testToRun.parameters) {
Object.entries(testToRun.parameters).forEach(([key, value]) => {
parameters.push({
_attributes: {
name: key,
value: value,
type: "string",
},
});
});
}
return {
_attributes: {
name: testToRun.testName,
path:
testToRun.className.replace("file:///", "") +
"/" +
testToRun.testName,
},
parameter: parameters,
};
});
const convertedTestsToRun = js2xml(
{
mtbx: {
test: uftTestsToRun,
},
},
{ compact: true },
);
LOGGER.debug(
`Successfully converted the tests to run: ${convertedTestsToRun}`,
);
return convertedTestsToRun;
};
const convertCustomTestsToRun = (testsToRun: Test[]): string => {
LOGGER.info(`Converting testsToRun to a custom format...`);
const customFramework = getConfig().customFramework;
if (!customFramework) {
throw new Error(
`Missing 'customFramework' argument for converting custom framework.`,
);
}
const frameworkConfig = parseCustomFramework(customFramework);
const customTestPattern = frameworkConfig.testPattern;
const customTestDelimiter = frameworkConfig.testDelimiter;
const customTestListPrefix = frameworkConfig.prefix || "";
const customTestListSuffix = frameworkConfig.suffix || "";
LOGGER.debug(`Using the following test pattern: '${customTestPattern}'`);
if (!customTestPattern || !customTestDelimiter) {
throw Error(
"To convert the tests to run for a custom framework, the testPattern and testDelimiter parameters are mandatory.",
);
}
const allowedTestsToRun = frameworkConfig.allowDuplication
? testsToRun
: Array.from(new Set(testsToRun.map((test) => JSON.stringify(test)))).map(
(test) => JSON.parse(test),
);
let convertedTestsToRun = allowedTestsToRun
.map((testToRun) =>
replaceCustomFrameworkPlaceholders(
customTestPattern,
testToRun,
frameworkConfig.replacements,
),
)
.join(customTestDelimiter);
convertedTestsToRun = `${customTestListPrefix}${convertedTestsToRun}${customTestListSuffix}`;
LOGGER.debug(
`Successfully converted the tests to run: ${convertedTestsToRun}`,
);
return convertedTestsToRun;
};
const replaceCustomFrameworkPlaceholders = (
pattern: string,
testToRun: Test,
replacements?: Replacement[],
): string => {
const packageName = applyReplacements(
testToRun.packageName,
replacements,
"$package",
);
const className = applyReplacements(
testToRun.className,
replacements,
"$class",
);
const testName = applyReplacements(
testToRun.testName,
replacements,
"$testName",
);
let result = pattern
.replace(CUSTOM_FRAMEWORK_PACKAGE_PLACEHOLDER, packageName)
.replace(CUSTOM_FRAMEWORK_CLASS_PLACEHOLDER, className)
.replace(CUSTOM_FRAMEWORK_TEST_PLACEHOLDER, testName);
return result;
};
const applyReplacements = (
input: string,
replacements: Replacement[] | undefined,
target: string,
): string => {
if (!replacements) return input;
return replacements.reduce((modifiedInput, replacement) => {
if (replacement.target !== target) return modifiedInput;
switch (replacement.type) {
case "replaceString":
return modifiedInput.replace(
new RegExp(replacement.string!, "g"),
replacement.replacement!,
);
case "replaceRegex":
return modifiedInput.replace(
new RegExp(replacement.regex!, "g"),
replacement.replacement!,
);
case "replaceRegexFirst":
return modifiedInput.replace(
new RegExp(replacement.regex!),
replacement.replacement!,
);
case "notLatinAndDigitToOctal":
return modifiedInput.replace(
/[^a-zA-Z0-9]/g,
(char) => `\\${char.charCodeAt(0).toString(8)}`,
);
case "joinString":
return `${replacement.prefix || ""}${modifiedInput}${replacement.suffix || ""}`;
case "toUpperCase":
return modifiedInput.toUpperCase();
case "toLowerCase":
return modifiedInput.toLowerCase();
default:
return modifiedInput;
}
}, input);
};
export default convertTestsToRun;