@microfocus/alm-octane-test-result-convertion
Version:
A NodeJS library for converting different kinds of test reports into OpenText SDP / SDM format.
191 lines (172 loc) • 6.89 kB
text/typescript
/*
* Copyright 2024-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 escapeXML from 'xml-escape';
import { js2xml, xml2js } from 'xml-js';
import { TestRunResult } from '../model/octane/TestRun';
import TestsResult from '../model/octane/TestsResult';
import OctaneBuildConfig from './OctaneBuildConfig';
import MultipleFeaturesRoot from '../model/gherkin/MultipleFeaturesRoot';
import Feature from '../model/gherkin/Feature';
import GherkinTestRun from '../model/octane/GherkinTestRun';
import { FrameworkType } from '../model/common/FrameworkType';
const FAILED_STATUS_LOWER_CASE: string = TestRunResult.FAILED.toLowerCase();
/**
* Convert Gherkin format XML to OpenText SDP / SDM format XML
* @param {string} gherkinXML - string containing Gherkin format XML
* @param {OctaneBuildConfig} octaneBuildConfig - OpenText SDP / SDM build configuration data (eg.: job id, buiild id, server id etc.)
* @param {FrameworkType} framework - Testing framework used to run the automated tests
* @returns {string} - string containing converted XML (returns the OpenText SDP / SDM format XML)
*/
const convertGherkinXMLToOctaneXML = (
gherkinXML: string,
octaneBuildConfig: OctaneBuildConfig,
framework: FrameworkType
): string => {
const gherkinReportJSON = xml2js(gherkinXML, { compact: true });
const octaneReportJSON = createOctaneTestsResult(
<MultipleFeaturesRoot>gherkinReportJSON,
octaneBuildConfig,
framework
);
return js2xml(octaneReportJSON, { compact: true });
};
/**
* Creates OpenText SDP / SDM test results object from Gherkin XML root object
* @param {MultipleFeaturesRoot} gherkinReport - Gherkin XML root object
* @param {OctaneBuildConfig} buildConfig - OpenText SDP / SDM build configuration data (eg.: job id, build id, server id etc.)
* @param {FrameworkType} framework - Testing framework used to run the automated tests
* @returns {TestsResult} - OpenText SDP / SDM tests result object to be converted to XML
*/
const createOctaneTestsResult = (
gherkinReport: MultipleFeaturesRoot,
buildConfig: OctaneBuildConfig,
framework: FrameworkType
): TestsResult => {
return {
test_result: {
build: {
_attributes: {
...buildConfig
}
},
test_fields: {
test_field: [
{
_attributes: {
type: 'Test_Level',
value: 'Gherkin Test'
}
},
{
_attributes: {
type: 'Test_Type',
value: 'Sanity'
}
},
{
_attributes: {
type: 'Framework',
value: framework
}
}
]
},
test_runs: {
gherkin_test_run: convertGherkinSuiteToOctaneRuns(gherkinReport)
}
}
};
};
/**
* Converts Gherkin root object to a list of OpenText SDP / SDM Test Run objects
* @param {MultipleFeaturesRoot} reportRoot - Gherkin XML root object
* @returns {GherkinTestRun[]} - list of Gherkin Test Run OpenText SDP / SDM objects
*/
const convertGherkinSuiteToOctaneRuns = (
reportRoot: MultipleFeaturesRoot
): GherkinTestRun[] => {
const octaneTestRuns: GherkinTestRun[] = [];
const features = convertToArray(reportRoot.features.feature);
features.forEach(featureElement => {
octaneTestRuns.push(mapTestCaseToOctaneRun(featureElement));
});
return octaneTestRuns;
};
/**
* Maps a Gherkin Feature object to an OpenText SDP / SDM TestRun object
* @param {Feature} feature - Gherkin Feature object
* @returns {GherkinTestRun} - resulted OpenText SDP / SDM TestRun object
*/
const mapTestCaseToOctaneRun = (featureElement: Feature): GherkinTestRun => {
let featureDuration: number = 0;
let featureStatus: TestRunResult = TestRunResult.PASSED;
featureElement._attributes.name = escapeXML(featureElement._attributes.name);
const scenarios = convertToArray(featureElement.scenarios.scenario);
scenarios.forEach(scenarioElement => {
scenarioElement._attributes.name = escapeXML(scenarioElement._attributes.name);
if (scenarioElement.steps) {
const steps = convertToArray(scenarioElement.steps.step);
if (steps && steps.length) {
let scenarioStatus: TestRunResult = TestRunResult.PASSED;
steps.forEach(stepElement => {
stepElement._attributes.name = escapeXML(stepElement._attributes.name);
featureDuration += Number(stepElement._attributes.duration);
if (stepElement._attributes.status.toLowerCase() === FAILED_STATUS_LOWER_CASE) {
scenarioStatus = TestRunResult.FAILED;
}
});
scenarioElement._attributes.status = scenarioStatus;
if (scenarioStatus.toLowerCase() === FAILED_STATUS_LOWER_CASE) {
featureStatus = scenarioStatus;
}
}
}
});
const testRun: GherkinTestRun = {
_attributes: {
name: featureElement._attributes.name,
duration: featureDuration,
status: featureStatus
},
feature: featureElement
};
return testRun;
};
/**
* Ensures an element is an array. If element is not already an array, then it is wrapped inside an array.
* @param {Type} elem - element to be checked
* @returns {Type[]} - the element array
*/
const convertToArray = <Type>(elem: Type | Type[]): Type[] => {
if (!Array.isArray(elem)) {
return [elem];
}
return elem;
};
export default convertGherkinXMLToOctaneXML;