UNPKG

@dbouckaert/zephyr-scale-cloud-reporter

Version:

ZH Cloud, or zephyr helpers is a Node JS framework that implements test suites with Zephyr scale for Jira. It uses a soft-assert function to absorb failing assertions and translate them to a true/false value.

447 lines (446 loc) 15.9 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.softAssert = exports.createNewTestExecution = exports.logStatusNames = exports.logEnvironmentNames = exports.init = void 0; /* eslint-disable @typescript-eslint/no-unused-expressions */ /* eslint-disable no-console */ const supertest_1 = __importDefault(require("supertest")); const chai_1 = require("chai"); const variables_interface_1 = require("./interfaces/variables.interface"); /** * This function checks the value of all the keys in an object, if the value is **undefined** an error is logged. * @param {object} obj the object to check * @param {string} msg the name of the function calling this (used for error logging) */ const validateObjectValues = (obj, msg) => { const paramsUndefined = Object.values(obj).includes(undefined); if (paramsUndefined) { console.log(obj); throw new Error(`ERROR: [${msg}] one, or more, parameter(s) value is UNDEFINED`); } }; const variables = variables_interface_1.defaultVariables; /** * This function sets a range of variables the Zephyr module uses * @param {ZephyrConfig} zephyrConfig */ async function init(zephyrConfig) { validateObjectValues(zephyrConfig, 'init'); variables.zephyrURL = zephyrConfig.zephyrURL; variables.jiraURL = zephyrConfig.jiraURL; variables.zephyrApiToken = zephyrConfig.zephyrApiToken; variables.jiraApiToken = zephyrConfig.jiraApiToken; variables.projectKey = zephyrConfig.zephyrProjectKey; variables.defaultJiraDisplayName = zephyrConfig.defaultJiraDisplayName; variables.jiraDisplayName = zephyrConfig.jiraDisplayName; } exports.init = init; const getJiraAccounts = async () => { let accounts; await (0, supertest_1.default)(variables.jiraURL) .get(`/rest/api/2/user/search?query&maxResults=2000`) .set('Authorization', `Basic ${variables.jiraApiToken}`) .then((res) => { accounts = res.body; }); return accounts; }; const getJiraAccountId = async () => { let accountId; const allAccounts = await getJiraAccounts(); accountId = allAccounts.find((account) => account.displayName === variables.jiraDisplayName).accountId; if (accountId === undefined) { accountId = allAccounts.find((account) => account.displayName === variables.defaultJiraDisplayName).accountId; } return accountId; }; const getEnvironmentNames = async () => { let environments; await (0, supertest_1.default)(variables.zephyrURL) .get(`/environments?projectKey=${variables.projectKey}`) .set('Authorization', `Bearer ${variables.zephyrApiToken}`) .then((res) => { environments = JSON.parse(res.text); }); return environments; }; const logEnvironmentNames = async () => { const allEnvironments = await getEnvironmentNames(); allEnvironments.values.forEach((env) => console.log(`Available environment: ${env.name}`)); }; exports.logEnvironmentNames = logEnvironmentNames; const getTestCases = async (folderName) => { let testcases; try { const folder_id = await getFolderId(folderName); await (0, supertest_1.default)(variables.zephyrURL) .get(`/testcases?maxResults=1000&projectKey=${variables.projectKey}&folderId=${folder_id}`) .set('Authorization', `Bearer ${variables.zephyrApiToken}`) .then((res) => { testcases = JSON.parse(res.text); }); return testcases; } catch (err) { console.log(`ERROR [getTestCases] - ${err}`); } }; const getTestCaseKey = async (folderName, testCaseName) => { //TODO what if no match if found for this specific testcasename/folder let key; const allTestCases = await getTestCases(folderName); // return de value van de key 'key' voor elke folder waar de value van de key 'name' gelijk is aan de naam die we zoeken allTestCases.values.forEach((testCase) => { if (testCase.name === testCaseName) { key = testCase.key; } }); return key; }; const getFolders = async () => { let folders; try { await (0, supertest_1.default)(variables.zephyrURL) .get(`/folders?maxResults=500&projectKey=${variables.projectKey}`) .set('Authorization', `Bearer ${variables.zephyrApiToken}`) .then((res) => { folders = JSON.parse(res.text); }); return folders; } catch (err) { console.log(`ERROR [getFolders] - ${err}`); } }; const getFolderId = async (folderName) => { let id; const allFolders = await getFolders(); // return de value van de key 'id' voor elke folder waar de value van de key 'name' gelijk is aan de naam die we zoeken allFolders.values.forEach((folder) => { if (folder.name === folderName) { id = folder.id; } }); if (id === undefined) console.log(`ERROR [getFolderId] - No folder found for name: ${folderName}`); return id; }; const getTestCycles = async () => { let testcycles; try { await (0, supertest_1.default)(variables.zephyrURL) .get(`/testcycles?maxResults=500&projectKey=${variables.projectKey}`) .set('Authorization', `Bearer ${variables.zephyrApiToken}`) .then((res) => { testcycles = JSON.parse(res.text); }); return testcycles; } catch (err) { console.log(`ERROR [getTestCycles] - ${err}`); } }; const getTestCycleKey = async (testCycleName) => { //TODO what if the test case isn't part of the test cycle? //! blijkbaar is dit geen probleem. let key; const allTestCycles = await getTestCycles(); // return de value van de key 'key' voor elke folder waar de value van de key 'name' gelijk is aan de naam die we zoeken allTestCycles.values.forEach((testCylce) => { if (testCylce.name === testCycleName) { key = testCylce.key; } }); if (key === undefined) console.log(`ERROR [getFolderId] - No test cylce found for name: ${testCycleName}`); return key; }; const getStatusNames = async () => { let statusNames; await (0, supertest_1.default)(variables.zephyrURL) .get(`/statuses?projectKey=${variables.projectKey}`) .set('Authorization', `Bearer ${variables.zephyrApiToken}`) .then((res) => { statusNames = JSON.parse(res.text); }); return statusNames; }; const logStatusNames = async () => { const allStatuses = await getStatusNames(); allStatuses.values.forEach((status) => console.log(`Available status: ${status.name}`)); }; exports.logStatusNames = logStatusNames; const createNewTestExecution = async (status, environmentName, folderName, testCaseName, testCycleName) => { let statusName; if (status === false) { statusName = 'Fail'; } else if (status === true) { statusName = 'Pass'; } else { console.log('ERROR [createNewTestExecution] please enter a valid test status'); } const payload = { projectKey: variables.projectKey, testCaseKey: await getTestCaseKey(folderName, testCaseName), testCycleKey: await getTestCycleKey(testCycleName), statusName, environmentName, executedById: await getJiraAccountId(), }; await (0, supertest_1.default)(variables.zephyrURL) .post(`/testexecutions`) .set('Authorization', `Bearer ${variables.zephyrApiToken}`) .send(payload) .then((res) => { const responseObj = JSON.parse(res.text); if (res.statusCode !== 201) { console.log(`ERROR [createNewTestExecution] ${responseObj.message}`); } else { console.log(`INFO [createNewTestExecution] - Succesfully create a new test execution\nID:${responseObj.id}\nURL:${responseObj.self}`); } }); }; exports.createNewTestExecution = createNewTestExecution; /** * Assert and capture errors. * While a normal failing assert would stop the code from running, the soft-assert can continue * And throws errors only if .assertAll() is called. */ exports.softAssert = { failedAsserts: [], equals(value, condition) { if (value === undefined || condition === undefined) { console.log('ERROR [equals] please provide the value and condition arguments'); process.exit(1); } let assertPassed = false; try { (0, chai_1.expect)(value).equal(condition); assertPassed = true; } catch (error) { const e = error; this.failedAsserts.push(e); } return assertPassed; }, notEquals(value, condition) { if (value === undefined || condition === undefined) { console.log('ERROR [notEquals] please provide the value and condition arguments'); process.exit(1); } let assertPassed = false; try { (0, chai_1.expect)(value).not.equal(condition); assertPassed = true; } catch (error) { const e = error; this.failedAsserts.push(e); } return assertPassed; }, deepEquals(value, condition) { if (value === undefined || condition === undefined) { console.log('ERROR [deepEquals] please provide the value and condition arguments'); process.exit(1); } let assertPassed = false; try { (0, chai_1.expect)(value).deep.equal(condition); assertPassed = true; } catch (error) { const e = error; this.failedAsserts.push(e); } return assertPassed; }, includes(sample, pattern) { if (sample === undefined || pattern === undefined) { console.log('ERROR [includes] please provide the sample and pattern arguments'); process.exit(1); } let assertPassed = false; if (Array.isArray(sample) === true && Array.isArray(pattern) === true) { console.log('sample is object or array'); try { (0, chai_1.expect)(sample).include.members(pattern); assertPassed = true; } catch (error) { const e = error; this.failedAsserts.push(e); } } else { try { (0, chai_1.expect)(sample).deep.include(pattern); assertPassed = true; } catch (error) { const e = error; this.failedAsserts.push(e); } } return assertPassed; }, notIncludes(sample, pattern) { if (sample === undefined || pattern === undefined) { console.log('ERROR [notIncludes] please provide the sample and pattern arguments'); process.exit(1); } let assertPassed = false; if (Array.isArray(sample) === true && Array.isArray(pattern) === true) { console.log('sample is object or array'); try { (0, chai_1.expect)(sample).not.include.members(pattern); assertPassed = true; } catch (error) { const e = error; this.failedAsserts.push(e); } } else { try { (0, chai_1.expect)(sample).not.deep.include(pattern); assertPassed = true; } catch (error) { const e = error; this.failedAsserts.push(e); } } return assertPassed; }, isUndefined(value) { let assertPassed = false; try { (0, chai_1.expect)(value).equal(undefined); assertPassed = true; } catch (error) { const e = error; this.failedAsserts.push(e); } return assertPassed; }, isNull(value) { let assertPassed = false; try { // eslint-disable-next-line @typescript-eslint/no-unused-expressions (0, chai_1.expect)(value).to.be.null; assertPassed = true; } catch (error) { const e = error; this.failedAsserts.push(e); } return assertPassed; }, /** * @param {object} params object & array * @returns true or false */ objectHasAllKeys(obj, arrayWithKeys) { if (!obj || !arrayWithKeys) { console.log('ERROR [objectHasAllKeys] please provide the sample and pattern arguments'); process.exit(1); } if (Array.isArray(arrayWithKeys) !== true) { console.log('ERROR [objectHasAllKeys] please pass an array as the arguments for "arrayWithKeys"'); process.exit(1); } if (typeof obj !== 'object' || Array.isArray(obj) === true) { console.log('ERROR: [objectHasAllKeys] argument type of argument "obj" is not an object'); process.exit(1); } let assertPassed; try { (0, chai_1.expect)(obj).to.have.all.keys(arrayWithKeys); assertPassed = true; } catch (error) { const e = error; this.failedAsserts.push(e); assertPassed = false; } return assertPassed; }, isEmptyObject(obj) { let assertPassed = false; if (!obj || typeof obj !== 'object' || Array.isArray(obj) === true) { console.log('WARNING [isEmptyObject] "obj" argument is not an object!'); } try { (0, chai_1.expect)(Object.keys(obj)).lengthOf(0); assertPassed = true; } catch (error) { const e = error; this.failedAsserts.push(e); } return assertPassed; }, /** * Usefull to check e.g. if a propterty in an object has a value */ hasLength(value) { let assertPassed = false; if (!value) { console.log('ERROR [hasLength] please pass an argument'); process.exit(1); } if (typeof value === 'string' || typeof value === 'object') { try { (0, chai_1.expect)(value).not.be.empty; assertPassed = true; } catch (error) { const e = error; this.failedAsserts.push(e); } } if (typeof value === 'number') { try { (0, chai_1.expect)(value).not.be.null; } catch (error) { const e = error; this.failedAsserts.push(e); assertPassed = false; } } return assertPassed; }, isOneOf(arr, value) { let assertPassed = false; if (!value) { console.log('ERROR [isOneOf] please pass an argument'); process.exit(1); } try { (0, chai_1.expect)(value).to.be.oneOf(arr); assertPassed = true; } catch (error) { const e = error; this.failedAsserts.push(e); } return assertPassed; }, /** * Use this function at the end of a test to check if any of the soft-asserts failed. * Thow an assert.fail if any errors were captured. */ assertAll: async function assertAll() { if (this.failedAsserts.length > 0) { const copyOfFailedAsserts = [...this.failedAsserts]; this.failedAsserts.length = 0; chai_1.assert.fail(copyOfFailedAsserts.join(', \n')); } }, };