updated revision number

refactored testrail api to be more seperate and able to use on its own
added get cases api call
This commit is contained in:
Pierre Awaragi
2017-07-25 12:25:42 -04:00
parent 04c12c4e80
commit 1c0c6115c5
7 changed files with 171 additions and 74 deletions

View File

@@ -1,7 +1,7 @@
{
"name": "mocha-testrail-reporter",
"version": "1.0.11",
"description": "A Testrail reporter for mocha.",
"version": "1.0.12",
"description": "A Testrail reporter for mocha including TestRail API basic library",
"main": "index.js",
"private": false,
"keywords": [

View File

@@ -1,10 +1,11 @@
import {reporters} from 'mocha';
import {TestRail} from "./testrail";
import {titleToCaseIds} from "./shared";
import {Status, TestRailResult} from "./testrail.interface";
export class MochaTestRailReporter extends reporters.Spec {
private testCases: TestCase[] = [];
private results: TestRailResult[] = [];
private passes: number = 0;
private fails: number = 0;
private pending: number = 0;
@@ -40,23 +41,23 @@ export class MochaTestRailReporter extends reporters.Spec {
let caseIds = titleToCaseIds(test.title);
if (caseIds.length > 0) {
if (test.speed === 'fast') {
let testCases = caseIds.map(caseId => {
let results = caseIds.map(caseId => {
return {
caseId: caseId,
pass: true,
case_id: caseId,
status_id: Status.Passed,
comment: test.title
};
});
this.testCases.push(...testCases);
this.results.push(...results);
} else {
let testCases = caseIds.map(caseId => {
let results = caseIds.map(caseId => {
return {
caseId: caseId,
pass: true,
case_id: caseId,
status_id: Status.Passed,
comment: `${test.title} (${test.duration}ms)`
};
});
this.testCases.push(...testCases);
this.results.push(...results);
}
}
});
@@ -66,23 +67,36 @@ export class MochaTestRailReporter extends reporters.Spec {
this.out.push(test.fullTitle() + ': fail');
let caseIds = titleToCaseIds(test.title);
if (caseIds.length > 0) {
let testCases = caseIds.map(caseId => {
let results = caseIds.map(caseId => {
return {
caseId: caseId,
pass: false,
case_id: caseId,
status_id: Status.Failed,
comment: `${test.title}
${test.err}`
};
});
this.testCases.push(...testCases);
this.results.push(...results);
}
});
runner.on('end', () => {
if (this.testCases.length == 0) {
if (this.results.length == 0) {
console.warn("No testcases were matched. Ensure that your tests are declared correctly and matches TCxxx");
}
new TestRail(reporterOptions).publish(this.passes, this.fails, this.pending, this.out, this.testCases);
let executionDateTime = new Date().toISOString();
let total = this.passes + this.fails + this.pending;
let name = `Automated test run ${executionDateTime}`;
let description = `Automated test run executed on ${executionDateTime}
Execution summary:
Passes: ${this.passes}
Fails: ${this.fails}
Pending: ${this.pending}
Total: ${total}
Execution details:
${this.out.join('\n')}
`;
new TestRail(reporterOptions).publish(name, description, this.results);
});
}

View File

@@ -1,5 +0,0 @@
interface TestCase {
caseId: number,
pass: boolean,
comment?: String,
}

View File

@@ -1,8 +0,0 @@
interface TestRailOptions {
domain: string,
username: string,
password: string,
projectId: number,
suiteId: number,
assignedToId?: number,
}

View File

@@ -0,0 +1,46 @@
export interface TestRailOptions {
domain: string,
username: string,
password: string,
projectId: number,
suiteId: number,
assignedToId?: number,
}
export enum Status {
Passed = 1,
Blocked = 2,
Untested = 3,
Retest = 4,
Failed = 5
}
export interface TestRailResult {
case_id: number,
status_id: Status,
comment?: String,
}
export interface TestRailCase {
id: number,
title: string,
section_id: number,
template_id: number,
type_id: number,
priority_id: number,
milestone_id?: number,
refs?: string,
created_by: number,
created_on: number,
updated_by: number,
updated_on: number,
estimate?: string,
estimate_forecast?: string,
suite_id: number,
custom_preconds?: string,
custom_steps?: string,
custom_expected?: string,
custom_steps_separated?: string,
custom_mission?: string,
custom_goals?: string
}

View File

@@ -1,6 +1,9 @@
import btoa = require('btoa');
import unirest = require("unirest");
import request = require("unirest");
import {TestRailOptions, TestRailResult} from "./testrail.interface";
/**
* TestRail basic API wrapper
*/
export class TestRail {
private base: String;
@@ -10,7 +13,7 @@ export class TestRail {
}
private _post(api: String, body: any, callback: Function, error?: Function) {
var req = unirest("POST", this.base)
var req = request("POST", this.base)
.query(`/api/v2/${api}`)
.headers({
"content-type": "application/json"
@@ -31,32 +34,63 @@ export class TestRail {
});
}
publish(passes: number, fails: number, pending: number, out: string[], tests: TestCase[], callback?: Function): void {
let total = passes + fails + pending;
let results: any = [];
for (let test of tests) {
results.push({
"case_id": test.caseId,
"status_id": test.pass ? 1 : 5,
"comment": test.comment ? test.comment: "",
private _get(api: String, callback: Function, error?: Function) {
var req = request("GET", this.base)
.query(`/api/v2/${api}`)
.headers({
"content-type": "application/json"
})
.type("json")
.auth(this.options.username, this.options.password)
.end((res) => {
if (res.error) {
console.log("Error: %s", JSON.stringify(res.body));
if (error) {
error(res.error);
} else {
throw new Error(res.error);
}
}
callback(res.body);
});
}
/**
* Fetchs test cases from projet/suite based on filtering criteria (optional)
* @param {{[p: string]: number[]}} filters
* @param {Function} callback
*/
public fetchCases(filters?: { [key: string]: number[] }, callback?: Function): void {
let filter = "";
if(filters) {
for (var key in filters) {
if (filters.hasOwnProperty(key)) {
filter += "&" + key + "=" + filters[key].join(",");
}
}
}
console.log(`Publishing ${results.length} test result(s) to ${this.base}`)
let executionDateTime = new Date().toISOString();
let req = this._get(`get_cases/${this.options.projectId}&suite_id=${this.options.suiteId}${filter}`, (body) => {
if (callback) {
callback(body);
}
});
}
/**
* Publishes results of execution of an automated test run
* @param {string} name
* @param {string} description
* @param {TestRailResult[]} results
* @param {Function} callback
*/
public publish(name: string, description: string, results: TestRailResult[], callback?: Function): void {
console.log(`Publishing ${results.length} test result(s) to ${this.base}`);
this._post(`add_run/${this.options.projectId}`, {
"suite_id": this.options.suiteId,
"name": `Automated test run ${executionDateTime}`,
"description": `Automated test run executed on ${executionDateTime}
Execution summary:
Passes: ${passes}
Fails: ${fails}
Pending: ${pending}
Total: ${total}
Execution details:
${out.join('\n')}
`,
"name": name,
"description": description,
"assignedto_id": this.options.assignedToId,
"include_all": true
}, (body) => {
@@ -66,7 +100,7 @@ ${out.join('\n')}
results: results
}, (body) => {
// execute callback if specified
if(callback) {
if (callback) {
callback();
}
})

View File

@@ -1,23 +1,39 @@
import {TestRail} from "../lib/testrail";
import {TestRailResult, TestRailCase, Status} from "../lib/testrail.interface";
describe.skip("TestRail API", () => {
describe("TestRail API", () => {
it("Publish test run", (done) => {
new TestRail({
domain: "testingoutone",
username: "testingout.one@mailinator.com",
password: "XyMp8uojG3wkzNNNXiTk-dP4MnBmOiQhVC2xGvmyY",
projectId: 1,
suiteId: 2,
assignedToId: 1,
}).publish(0, 0, 0, ["test 1: pass", "test 2: fail"], [
{
caseId: 74,
pass: true
}, {
caseId: 75,
pass: false,
comment: "Failure...."
}
], done);
})
let testRail = new TestRail({
domain: process.env.DOMAIN,
username: process.env.USERNAME,
password: process.env.PASSWORD,
projectId: 10,
suiteId: 104,
// assignedToId: 2,
});
testRail.fetchCases({type_id: [3], priority_id: [4]}, (cases: TestRailCase[]) => {
console.log(cases);
let results: TestRailResult
cases.forEach((value => {
console.log(value.id, value.title);
}));
});
testRail.publish("Unit Test of mocha-testrail-reporter", "Unit Test of mocha-testrail-reporter", [{
case_id: 3033,
status_id: Status.Passed,
comment: "Passing...."
}, {
case_id: 3034,
status_id: Status.Passed
}, {
case_id: 3035,
status_id: Status.Passed
}, {
case_id: 3036,
status_id: Status.Failed,
comment: "Failure...."
}], done);
});
});