testrail-jest-reporter
Advanced tools
Comparing version
{ | ||
"name": "testrail-jest-reporter", | ||
"version": "1.0.6", | ||
"version": "1.0.7", | ||
"description": "Custom Jest reporter for Testrail synchronization", | ||
@@ -55,4 +55,6 @@ "main": "index.js", | ||
"dependencies": { | ||
"@prantlf/jsonlint": "^10.2.0", | ||
"chalk": "^4.1.0", | ||
"fs-extra": "^9.0.1", | ||
"lodash": "^4.17.20", | ||
"process": "^0.11.10", | ||
@@ -59,0 +61,0 @@ "request": "^2.88.2", |
@@ -138,2 +138,4 @@ [](http://docs.gurock.com/testrail-api2/start) [](https://github.com/AntonChaukin/testrail-jest-reporter/blob/main/LICENSE) [](https://github.com/AntonChaukin/testrail-jest-reporter/blob/main/package.json) | ||
- ~~Added ability to specify several case_ids in one test description~~ >> **Done in 1.0.6** | ||
- ~~Added JSON validator to API interface~~ >> **Done in 1.0.7** | ||
- Migrate to GOT | ||
@@ -140,0 +142,0 @@ <br>**Version 2:** |
'use strict'; | ||
const chalk = require('chalk'), tr_api = require('./interface'), Utils = require('./utils'), | ||
ReporterError = require('./error'); | ||
const chalk = require('chalk'), tr_api = require('./interface'), ReporterError = require('./error'); | ||
const error = chalk.bold.red; | ||
const util = new Utils(); | ||
@@ -18,22 +16,8 @@ module.exports = { | ||
tr_api.defaults.headers['Authorization'] = _options.auth; | ||
tr_api.defaults.uri = this._baseUrl + '/index.php?/api/v2/'; | ||
tr_api.defaults.baseUrl = this._baseUrl + '/index.php?/api/v2/'; | ||
} | ||
function add_results(testsResults) { | ||
if (!util.isArray(testsResults)) { | ||
throw new ReporterError(`Something was wrong with tests results! | ||
\n\nContexts: ${JSON.stringify(testsResults)}`); | ||
} | ||
return Promise.all( | ||
testsResults.map(run => { | ||
if (!util.isArray(run.results)) { | ||
throw new ReporterError(`The Run results is not an array! | ||
\n\n Context: ${JSON.stringify(run.results)}`); | ||
} | ||
for(let i=0, len=run.results.length; i<len; i++) { | ||
if (!util.isPlainObject(run.results[i])) { | ||
throw new ReporterError(`Something was wrong with the Run results! | ||
\n\n Context: ${JSON.stringify(run.results)}`); | ||
} | ||
} | ||
return tr_api.add_results_for_cases(run.id, {"results": run.results}); | ||
@@ -45,15 +29,5 @@ }) | ||
response.map(run => { | ||
if (run) { | ||
switch (run.statusCode) { | ||
case 200: | ||
if (util.isArray(run.body)) run.body.map((result) => { | ||
if (result && result.id) count++; | ||
}); | ||
break; | ||
case 500: | ||
throw new ReporterError(run.error); | ||
default: | ||
throw new ReporterError(`TestRail API add_results_for_cases resolved ${JSON.stringify(run)}`); | ||
} | ||
} else throw new ReporterError(`TestRail API add_results_for_cases resolved ${JSON.stringify(run)}`); | ||
run.map((result) => { | ||
if (result && result.id) count++; | ||
}); | ||
}); | ||
@@ -74,6 +48,3 @@ return count; | ||
.then(res => { | ||
let _milestone = null; | ||
if (res && util.isArray(res)) { | ||
_milestone = res.filter((milestone) => milestone.name === this._milestone_name); | ||
} else throw new ReporterError(`TestRail API get_milestones resolved ${JSON.stringify(res)}`); | ||
const _milestone = res.filter((milestone) => milestone.name === this._milestone_name); | ||
@@ -87,6 +58,5 @@ if (_milestone && !!_milestone.length) { | ||
.then(res => { | ||
if (res && util.isArray(res)) { | ||
if (res) { | ||
return Promise.all(res.map(plan => tr_api.get_plan(plan.id))); | ||
} | ||
else if (this._milestone_id) throw new ReporterError(`TestRail API get_plans resolved ${JSON.stringify(res)}`); | ||
return false; | ||
@@ -99,5 +69,5 @@ }) | ||
.then(res => { | ||
for(let i=0, res_len=res.length; i<res_len; i++) { | ||
const plan = res[i]; | ||
if (plan && plan.entries) { | ||
if (res) { | ||
for(let i=0, res_len=res.length; i<res_len; i++) { | ||
const plan = res[i]; | ||
for (let j=0, len = plan.entries.length; j<len; j++) { | ||
@@ -107,3 +77,2 @@ plan.entries[j].runs.map(run => this._runs_ids.push(run.id)); | ||
} | ||
else console.log(error(`TestRail API get_plan resolved ${JSON.stringify(res[i])}`)); | ||
} | ||
@@ -120,3 +89,3 @@ if (this._milestone_id) { | ||
.then(res => { | ||
if (res && util.isArray(res)) { | ||
if (res) { | ||
for (let i=0, len = res.length; i<len; i++) { | ||
@@ -132,5 +101,5 @@ if (res[i] && res[i].id) this._runs_ids.push(res[i].id); | ||
.then(res => { | ||
for(let i=0, len=res.length; i<len; i++) { | ||
const tests = res[i]; | ||
if (tests && util.isArray(tests)) { | ||
if (res) { | ||
for(let i=0, len=res.length; i<len; i++) { | ||
const tests = res[i]; | ||
for(let j=0, t_len=tests.length; j<t_len; j++) { | ||
@@ -140,3 +109,3 @@ if (tests[j] && tests[j].case_id) this._tests | ||
} | ||
} else console.log(error(`TestRail API get_tests resolved ${JSON.stringify(res[i])}`)); | ||
} | ||
} | ||
@@ -143,0 +112,0 @@ if (!!this._tests.length) { |
'use strict'; | ||
const rp = require('request-promise'), chalk = require('chalk'), Utils = require('./utils'); | ||
const rp = require('request-promise'), chalk = require('chalk'), Utils = require('./utils'), | ||
ReporterError = require('./error'), {compile} = require('@prantlf/jsonlint/lib/validator'), | ||
{body: schema_body, data: schema_data} = require('./schemas'); | ||
const error = chalk.bold.red; | ||
@@ -10,7 +12,7 @@ const utils = new Utils(); | ||
headers: { | ||
'Authorization': null, | ||
'Content-Type': 'application/json' | ||
}, | ||
json: true, | ||
jar: true | ||
jar: true, | ||
resolveWithFullResponse: true | ||
} | ||
@@ -25,21 +27,52 @@ | ||
* | ||
* @param {Object} config The config specific for this request (merged with this.defaults) | ||
* @param {string} uri | ||
* @param {array} args The config specific for this request (merged with this.defaults) | ||
*/ | ||
Testrail_api.prototype.request = function request(config) { | ||
if (typeof config === 'string') { | ||
config = arguments[1] || {}; | ||
config.uri = arguments[0]; | ||
Testrail_api.prototype.request = function request(uri, ...args) { | ||
const _base = rp.defaults(this.defaults); | ||
let caller; | ||
let _path = uri; | ||
const data = utils.isPlainObject(args[args.length - 1]) ? args[args.length - 1] : null; | ||
if (data) args.pop(); | ||
if(utils.isPlainObject(args[0]) && args[0].method === 'POST') { | ||
args.shift(); | ||
const validate_data = compile(JSON.stringify(schema_data[uri])); | ||
try { | ||
validate_data(JSON.stringify(data)); | ||
} | ||
catch (err) { | ||
throw new ReporterError(`\nInvalid request data for method ${uri} | ||
Context: ${JSON.stringify(data)}\n${err.message}`); | ||
} | ||
caller = _base.defaults({ | ||
method: 'POST', | ||
body: data, | ||
followAllRedirects: true | ||
}); | ||
} else { | ||
config = config || {}; | ||
caller =_base.defaults({qs: data}); | ||
} | ||
config = mergeConfig(this.defaults, config); | ||
for(let i=0, len = args.length; i<len; i++) {_path += `/${args[i]}`} | ||
if (config.method) { | ||
config.method = config.method.toUpperCase(); | ||
} else if (this.defaults.method) { | ||
config.method = this.defaults.method.toUpperCase(); | ||
} | ||
return rp(config); | ||
return caller(_path) | ||
.then(resp => { | ||
switch (resp.statusCode) { | ||
case 200: | ||
break; | ||
default: | ||
throw new ReporterError(`\nUnexpected response status code ${resp.statusCode} | ||
\n${JSON.stringify(resp, null, 2)}`) | ||
} | ||
const validate_body = compile(JSON.stringify(schema_body[uri])); | ||
try { | ||
validate_body(JSON.stringify(resp.body)); | ||
} | ||
catch (err) { | ||
throw new ReporterError(`\nTestRail API response parsing error:\n${err.message}`); | ||
} | ||
return resp.body; | ||
}) | ||
.catch(error => {throw new ReporterError(`\n${error.message}`)}); | ||
}; | ||
@@ -50,14 +83,3 @@ | ||
Testrail_api.prototype[method] = function(...args) { | ||
const data = typeof args[args.length - 1] === 'object' ? args[args.length - 1] : null; | ||
if (data) args.pop(); | ||
let uri = method; | ||
for(let i=0, len = args.length; i<len; i++) {uri += `/${args[i]}`} | ||
return this.request({ | ||
method: 'POST', | ||
uri: uri, | ||
body: data, | ||
followAllRedirects: true, | ||
resolveWithFullResponse: true | ||
}).catch((err) => console.log(error(err))); | ||
return this.request(method, {method: 'POST'}, ...args) | ||
}; | ||
@@ -69,11 +91,3 @@ }); | ||
Testrail_api.prototype[method] = function(...args) { | ||
const data = typeof args[args.length - 1] === 'object' ? args[args.length - 1] : null; | ||
if (data) args.pop(); | ||
let uri = method; | ||
for(let i=0, len = args.length; i<len; i++) {uri += `/${args[i]}`} | ||
return this.request({ | ||
uri: uri, | ||
qs: data | ||
}).catch((err) => {throw new Error(err)}); | ||
return this.request(method, ...args) | ||
}; | ||
@@ -126,37 +140,1 @@ }); | ||
} | ||
function mergeConfig(config1, config2) { | ||
config2 = config2 || {}; | ||
let config = {}; | ||
let otherKeys = Object | ||
.keys(config1) | ||
.concat(Object.keys(config2)) | ||
.filter(function filterKeys(key) { | ||
return key !== 'headers' || key !== 'uri'; | ||
}); | ||
mergeProperties('headers'); | ||
utils.forEach(otherKeys, mergeProperties); | ||
config['uri'] = config1['uri'] + config2['uri']; | ||
return config; | ||
function getMergedValue(target, source) { | ||
if (utils.isPlainObject(target) && utils.isPlainObject(source)) { | ||
return utils.merge(target, source); | ||
} else if (utils.isPlainObject(source)) { | ||
return utils.merge({}, source); | ||
} else if (utils.isArray(source)) { | ||
return source.slice(); | ||
} | ||
return source; | ||
} | ||
function mergeProperties(prop) { | ||
if (typeof config2[prop] !== 'undefined') { | ||
config[prop] = getMergedValue(config1[prop], config2[prop]); | ||
} else if (typeof config1[prop] !== 'undefined') { | ||
config[prop] = getMergedValue(undefined, config1[prop]); | ||
} | ||
} | ||
} |
@@ -483,161 +483,2 @@ const Utils = require('../src/utils'), ReporterError = require('../src/error'); | ||
it('get_tests if get_plans return undefined', async () => { | ||
const caller = require('../src/caller'); | ||
const api = require('../src/interface'); | ||
caller.init({milestone: milestone_name, project_id: 1}); | ||
jest.spyOn(api, 'get_milestones').mockResolvedValueOnce(get_milestones_resp); | ||
jest.spyOn(api, 'get_plans').mockResolvedValueOnce(undefined); | ||
const get_plan_spy = jest.spyOn(api, 'get_plan').mockResolvedValueOnce(get_plan_resp); | ||
jest.spyOn(api, 'get_runs').mockResolvedValueOnce(get_runs_resp); | ||
const get_tests_spy = jest.spyOn(api, 'get_tests') | ||
.mockResolvedValueOnce([test_1]) | ||
.mockResolvedValueOnce([test_2]) | ||
.mockResolvedValue([]); | ||
await caller.get_tests(); | ||
get_plan_spy.mockRestore(); | ||
get_tests_spy.mockRestore(); | ||
expect(caller._tests).toEqual([case_1]); | ||
expect(caller._runs_ids).toHaveLength(1); | ||
expect(caller._milestone_id).toEqual(milestone_id); | ||
}); | ||
it('get_tests if get_plans return empty', async () => { | ||
const caller = require('../src/caller'); | ||
const api = require('../src/interface'); | ||
caller.init({milestone: milestone_name, project_id: 1}); | ||
jest.spyOn(api, 'get_milestones').mockResolvedValueOnce(get_milestones_resp); | ||
jest.spyOn(api, 'get_plans').mockResolvedValueOnce([{}]); | ||
jest.spyOn(api, 'get_plan').mockResolvedValueOnce({}); | ||
jest.spyOn(api, 'get_runs').mockResolvedValueOnce(get_runs_resp); | ||
const get_tests_spy = jest.spyOn(api, 'get_tests') | ||
.mockResolvedValueOnce([test_1]) | ||
.mockResolvedValueOnce([test_2]) | ||
.mockResolvedValue([]); | ||
await caller.get_tests(); | ||
get_tests_spy.mockRestore(); | ||
expect(caller._tests).toEqual([case_1]); | ||
expect(caller._runs_ids).toHaveLength(1); | ||
expect(caller._milestone_id).toEqual(milestone_id); | ||
}); | ||
it('get_tests if get_plan return undefined', async () => { | ||
const caller = require('../src/caller'); | ||
const api = require('../src/interface'); | ||
caller.init({milestone: milestone_name, project_id: 1}); | ||
jest.spyOn(api, 'get_milestones').mockResolvedValueOnce(get_milestones_resp); | ||
jest.spyOn(api, 'get_plans').mockResolvedValueOnce(get_plans_resp); | ||
jest.spyOn(api, 'get_plan').mockResolvedValueOnce(undefined); | ||
const get_runs_spy = jest.spyOn(api, 'get_runs').mockResolvedValueOnce(get_runs_resp); | ||
const get_tests_spy = jest.spyOn(api, 'get_tests') | ||
.mockResolvedValueOnce([test_1]) | ||
.mockResolvedValueOnce([test_2]) | ||
.mockResolvedValue([]); | ||
await caller.get_tests(); | ||
get_runs_spy.mockRestore(); | ||
get_tests_spy.mockRestore(); | ||
expect(caller._tests).toEqual([case_1]); | ||
expect(caller._runs_ids).toHaveLength(1); | ||
expect(caller._milestone_id).toEqual(milestone_id); | ||
}); | ||
it('get_tests if get_runs return undefined', async () => { | ||
const caller = require('../src/caller'); | ||
const api = require('../src/interface'); | ||
caller.init({milestone: milestone_name, project_id: 1}); | ||
jest.spyOn(api, 'get_milestones').mockResolvedValueOnce(get_milestones_resp); | ||
jest.spyOn(api, 'get_plans').mockResolvedValueOnce(get_plans_resp); | ||
jest.spyOn(api, 'get_plan').mockResolvedValueOnce(get_plan_resp); | ||
const get_runs_spy = jest.spyOn(api, 'get_runs').mockResolvedValueOnce(undefined); | ||
const get_tests_spy = jest.spyOn(api, 'get_tests') | ||
.mockResolvedValueOnce([test_2]) | ||
.mockResolvedValue([]); | ||
await caller.get_tests(); | ||
get_runs_spy.mockRestore(); | ||
get_tests_spy.mockRestore(); | ||
expect(caller._tests).toEqual([case_2]); | ||
expect(caller._runs_ids).toHaveLength(runs_len); | ||
expect(caller._milestone_id).toEqual(milestone_id); | ||
}); | ||
it('get_tests if get_runs return empty', async () => { | ||
const caller = require('../src/caller'); | ||
const api = require('../src/interface'); | ||
caller.init({milestone: milestone_name, project_id: 1}); | ||
jest.spyOn(api, 'get_milestones').mockResolvedValueOnce(get_milestones_resp); | ||
jest.spyOn(api, 'get_plans').mockResolvedValueOnce(get_plans_resp); | ||
jest.spyOn(api, 'get_plan').mockResolvedValueOnce(get_plan_resp); | ||
const get_runs_spy = jest.spyOn(api, 'get_runs').mockResolvedValueOnce([{}]); | ||
const get_tests_spy = jest.spyOn(api, 'get_tests') | ||
.mockResolvedValueOnce([test_2]) | ||
.mockResolvedValue([]); | ||
await caller.get_tests(); | ||
get_runs_spy.mockRestore(); | ||
get_tests_spy.mockRestore(); | ||
expect(caller._tests).toEqual([case_2]); | ||
expect(caller._runs_ids).toHaveLength(runs_len); | ||
expect(caller._milestone_id).toEqual(milestone_id); | ||
}); | ||
it('get_tests if get_tests return empty', async () => { | ||
const caller = require('../src/caller'); | ||
const api = require('../src/interface'); | ||
caller.init({milestone: milestone_name, project_id: 1}); | ||
jest.spyOn(api, 'get_milestones').mockResolvedValueOnce(get_milestones_resp); | ||
jest.spyOn(api, 'get_plans').mockResolvedValueOnce(get_plans_resp); | ||
jest.spyOn(api, 'get_plan').mockResolvedValueOnce(get_plan_resp); | ||
jest.spyOn(api, 'get_runs').mockResolvedValueOnce(get_runs_resp); | ||
const get_tests_spy = jest.spyOn(api, 'get_tests') | ||
.mockResolvedValue([]); | ||
await caller.get_tests(); | ||
get_tests_spy.mockRestore(); | ||
expect(caller._tests).toEqual([]); | ||
expect(caller._runs_ids).toHaveLength(runs_len+1); | ||
expect(caller._milestone_id).toEqual(milestone_id); | ||
}); | ||
it('get_tests if get_tests return undefined', async () => { | ||
const caller = require('../src/caller'); | ||
const api = require('../src/interface'); | ||
caller.init({milestone: milestone_name, project_id: 1}); | ||
jest.spyOn(api, 'get_milestones').mockResolvedValueOnce(get_milestones_resp); | ||
jest.spyOn(api, 'get_plans').mockResolvedValueOnce(get_plans_resp); | ||
jest.spyOn(api, 'get_plan').mockResolvedValueOnce(get_plan_resp); | ||
jest.spyOn(api, 'get_runs').mockResolvedValueOnce(get_runs_resp); | ||
const get_tests_spy = jest.spyOn(api, 'get_tests') | ||
.mockResolvedValue(undefined); | ||
await caller.get_tests(); | ||
get_tests_spy.mockRestore(); | ||
expect(caller._tests).toEqual([]); | ||
expect(caller._runs_ids).toHaveLength(runs_len+1); | ||
expect(caller._milestone_id).toEqual(milestone_id); | ||
}); | ||
it('add_results successful', async() => { | ||
@@ -652,3 +493,3 @@ const api = require('../src/interface'); | ||
const add_results_for_cases_spy = jest.spyOn(api, 'add_results_for_cases') | ||
.mockResolvedValueOnce(resp); | ||
.mockResolvedValueOnce(resp.body); | ||
@@ -669,3 +510,3 @@ const res = await caller.add_results([{id: 1, results: [testcase]}]); | ||
try { | ||
resp =await caller.add_results([{id: 1, results: [testcase]}]); | ||
resp = await caller.add_results([{id: 1, results: [testcase]}]); | ||
} | ||
@@ -686,3 +527,3 @@ catch (err) { | ||
try { | ||
resp =await caller.add_results([{id: 1, results: testcase}]); | ||
resp = await caller.add_results([{id: 1, results: testcase}]); | ||
} | ||
@@ -703,3 +544,3 @@ catch (err) { | ||
try { | ||
resp =await caller.add_results([{id: 1, results: [testcase, 'test']}]); | ||
resp = await caller.add_results([{id: 1, results: [testcase, 'test']}]); | ||
} | ||
@@ -712,23 +553,2 @@ catch (err) { | ||
it('add_results add_results_for_cases return error', async() => { | ||
const api = require('../src/interface'); | ||
const caller = require('../src/caller'); | ||
const console_spy = jest.spyOn(global.console, 'log'); | ||
let utils = new Utils(); | ||
const testResult = passed(); | ||
const [testcase] = utils.formatCase(testResult); | ||
const err = new Error('Request rejected'); | ||
const resp = {statusCode: 500, error: err}; | ||
const add_results_for_cases_spy = jest.spyOn(api, 'add_results_for_cases') | ||
.mockResolvedValueOnce(resp); | ||
const res = await caller.add_results([{id: 1, results: [testcase]}]); | ||
add_results_for_cases_spy.mockRestore(); | ||
expect(res).toBeFalsy(); | ||
expect(console_spy).toHaveBeenCalledWith(error("Testrail Jest Reporter Error: "+err)); | ||
console_spy.mockRestore(); | ||
}); | ||
it('add_results add_results_for_cases rejected', async() => { | ||
@@ -754,40 +574,4 @@ const api = require('../src/interface'); | ||
it('add_results add_results_for_cases return empty', async() => { | ||
const api = require('../src/interface'); | ||
const caller = require('../src/caller'); | ||
let utils = new Utils(); | ||
const testResult = passed(); | ||
const [testcase] = utils.formatCase(testResult); | ||
const add_results_for_cases_spy = jest.spyOn(api, 'add_results_for_cases') | ||
.mockResolvedValue({statusCode: 200, body: [{}]}); | ||
const res = await caller.add_results([{id: 1, results: [testcase]}]); | ||
add_results_for_cases_spy.mockRestore(); | ||
expect(res).toBeFalsy(); | ||
}); | ||
it('add_results add_results_for_cases return undefined', async() => { | ||
const api = require('../src/interface'); | ||
const caller = require('../src/caller'); | ||
const console_spy = jest.spyOn(global.console, 'log'); | ||
let utils = new Utils(); | ||
const err = new ReporterError("TestRail API add_results_for_cases resolved undefined"); | ||
const testResult = passed(); | ||
const [testcase] = utils.formatCase(testResult); | ||
const add_results_for_cases_spy = jest.spyOn(api, 'add_results_for_cases') | ||
.mockResolvedValue(undefined); | ||
const res = await caller.add_results([{id: 1, results: [testcase]}]); | ||
add_results_for_cases_spy.mockRestore(); | ||
expect(res).toBeFalsy(); | ||
expect(console_spy).toHaveBeenCalledWith(error(err)); | ||
console_spy.mockRestore() | ||
}); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
117897
15.59%17
21.43%2240
45.55%152
1.33%8
33.33%3
50%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added