diff --git a/dist/CucumberReportParser.js b/dist/CucumberReportParser.js new file mode 100644 index 0000000..980514e --- /dev/null +++ b/dist/CucumberReportParser.js @@ -0,0 +1,38 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class CucumberReportParser { + parseReport(report) { + this.report = report; + this.scenarios = []; + report.forEach((result) => { + let testCases = result.elements; + this.parseTestCases(testCases); + }); + return this.scenarios; + } + parseTestCases(testCases) { + testCases.forEach((testCase) => { + let error = this.parseTestCase(testCase); + const scenario = { + tags: [testCase.tags[0].name], + isPending: false, + isUndefined: false, + isSkipped: false, + isSuccessful: error === null, + exception: error, + }; + this.scenarios.push(scenario); + }); + } + parseTestCase(testCase) { + let error = null; + testCase.steps.forEach((step) => { + if (step.result.status !== 'passed') { + error = `status[${step.result.status}] step[${step.name}]`; + } + }); + return error; + } +} +exports.CucumberReportParser = CucumberReportParser; +//# sourceMappingURL=CucumberReportParser.js.map \ No newline at end of file diff --git a/dist/CucumberReportParser.js.map b/dist/CucumberReportParser.js.map new file mode 100644 index 0000000..107d45e --- /dev/null +++ b/dist/CucumberReportParser.js.map @@ -0,0 +1 @@ +{"version":3,"file":"CucumberReportParser.js","sourceRoot":"","sources":["../src/CucumberReportParser.ts"],"names":[],"mappings":";;AAEA;IAIS,WAAW,CAAC,MAAkB;QACnC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,SAAS,GAAG,EAAE,CAAA;QACnB,MAAM,CAAC,OAAO,CAAC,CAAC,MAAW,EAAE,EAAE;YAC7B,IAAI,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAA;YAC/B,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAA;QAChC,CAAC,CAAC,CAAA;QACF,OAAO,IAAI,CAAC,SAAS,CAAA;IACvB,CAAC;IAES,cAAc,CAAC,SAAqB;QAC5C,SAAS,CAAC,OAAO,CAAC,CAAC,QAAwB,EAAE,EAAE;YAC7C,IAAI,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAA;YACxC,MAAM,QAAQ,GAAa;gBACzB,IAAI,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;gBAC7B,SAAS,EAAE,KAAK;gBAChB,WAAW,EAAE,KAAK;gBAClB,SAAS,EAAE,KAAK;gBAChB,YAAY,EAAE,KAAK,KAAK,IAAI;gBAC5B,SAAS,EAAE,KAAK;aACjB,CAAA;YACD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QAC/B,CAAC,CAAC,CAAA;IACJ,CAAC;IAES,aAAa,CAAC,QAAa;QACnC,IAAI,KAAK,GAAG,IAAI,CAAA;QAChB,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAU,EAAE,EAAE;YACpC,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE;gBACnC,KAAK,GAAG,UAAU,IAAI,CAAC,MAAM,CAAC,MAAM,UAAU,IAAI,CAAC,IAAI,GAAG,CAAA;aAC3D;QACH,CAAC,CAAC,CAAA;QACF,OAAO,KAAK,CAAA;IACd,CAAC;CACF;AAtCD,oDAsCC"} \ No newline at end of file diff --git a/dist/bin/push-test-result-file.js b/dist/bin/push-test-result-file.js new file mode 100644 index 0000000..e5b5885 --- /dev/null +++ b/dist/bin/push-test-result-file.js @@ -0,0 +1,44 @@ +#!/usr/bin/env node +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const program = require("commander"); +const path = require("path"); +const index_1 = require("../index"); +let parser = new index_1.CucumberReportParser(); +program + .option('--file ', 'filename in results directory') + .parse(process.argv); +const error = (s) => { + program.outputHelp(); + console.log(); + console.log('Error: ' + s); + process.exit(1); +}; +if (!program.file || [0, NaN].indexOf(program.file) !== -1) { + error(' is required and must be a string'); +} +let config = index_1.readConfig(); +config.pushResults = true; +const resultFile = String(program.file); +let results; +try { + results = require(path.resolve(config.resultsDir, resultFile)); +} +catch (e) { + error(` error reading file[${path.resolve(config.resultsDir, resultFile)}] exception[${e}]`); +} +if (!Array.isArray(results)) { + error(` wrong cucumber format result file ${path.resolve(config.resultsDir, resultFile)}`); +} +const scenarios = parser.parseReport(results); +const sync = new index_1.ResultSynchronizer(config); +const savePromises = []; +for (const scenario of scenarios) { + savePromises.push(sync.saveTestResult(scenario)); +} +Promise.all(savePromises) + .then(() => sync.readRemoteTestRuns().then(() => sync.pushTestResults().then(function () { + console.log(`sync done`); +}))) + .catch(e => error(e)); +//# sourceMappingURL=push-test-result-file.js.map \ No newline at end of file diff --git a/dist/bin/push-test-result-file.js.map b/dist/bin/push-test-result-file.js.map new file mode 100644 index 0000000..cd703e6 --- /dev/null +++ b/dist/bin/push-test-result-file.js.map @@ -0,0 +1 @@ +{"version":3,"file":"push-test-result-file.js","sourceRoot":"","sources":["../../src/bin/push-test-result-file.ts"],"names":[],"mappings":";;;AACA,qCAAoC;AACpC,6BAA4B;AAC5B,oCAA+E;AAE/E,IAAI,MAAM,GAAG,IAAI,4BAAoB,EAAE,CAAA;AAEvC,OAAO;KACJ,MAAM,CAAC,iBAAiB,EAAE,+BAA+B,CAAC;KAC1D,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;AAEtB,MAAM,KAAK,GAAG,CAAC,CAAS,EAAQ,EAAE;IAChC,OAAO,CAAC,UAAU,EAAE,CAAA;IACpB,OAAO,CAAC,GAAG,EAAE,CAAA;IACb,OAAO,CAAC,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,CAAA;IAC1B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAA;AAED,IAAI,CAAO,OAAQ,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,OAAO,CAAO,OAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE;IACxE,KAAK,CAAC,kDAAkD,CAAC,CAAA;CAC1D;AACD,IAAI,MAAM,GAAG,kBAAU,EAAE,CAAA;AACzB,MAAM,CAAC,WAAW,GAAG,IAAI,CAAA;AAEzB,MAAM,UAAU,GAAG,MAAM,CAAO,OAAQ,CAAC,IAAI,CAAC,CAAA;AAC9C,IAAI,OAAO,CAAA;AACX,IAAI;IACF,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAA;CAC/D;AAAC,OAAO,CAAC,EAAE;IACV,KAAK,CACH,sCAAsC,IAAI,CAAC,OAAO,CAChD,MAAM,CAAC,UAAU,EACjB,UAAU,CACX,eAAe,CAAC,GAAG,CACrB,CAAA;CACF;AAED,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;IAC3B,KAAK,CACH,qDAAqD,IAAI,CAAC,OAAO,CAC/D,MAAM,CAAC,UAAU,EACjB,UAAU,CACX,EAAE,CACJ,CAAA;CACF;AAED,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;AAE7C,MAAM,IAAI,GAAG,IAAI,0BAAkB,CAAC,MAAM,CAAC,CAAA;AAC3C,MAAM,YAAY,GAAG,EAAE,CAAA;AACvB,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE;IAChC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAA;CACjD;AACD,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;KACtB,IAAI,CAAC,GAAG,EAAE,CACT,IAAI,CAAC,kBAAkB,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAClC,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,CAAC;IAC1B,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;AAC1B,CAAC,CAAC,CACH,CACF;KACA,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA"} \ No newline at end of file diff --git a/dist/index.js b/dist/index.js index a3a1838..4488bed 100644 --- a/dist/index.js +++ b/dist/index.js @@ -6,6 +6,8 @@ var ScenarioSynchronizer_1 = require("./ScenarioSynchronizer"); exports.ScenarioSynchronizer = ScenarioSynchronizer_1.ScenarioSynchronizer; var ResultSynchronizer_1 = require("./ResultSynchronizer"); exports.ResultSynchronizer = ResultSynchronizer_1.ResultSynchronizer; +var CucumberReportParser_1 = require("./CucumberReportParser"); +exports.CucumberReportParser = CucumberReportParser_1.CucumberReportParser; var readConfig_1 = require("./readConfig"); exports.readConfig = readConfig_1.readConfig; var install_1 = require("./install"); diff --git a/dist/index.js.map b/dist/index.js.map index 1ff911d..c7dddc2 100644 --- a/dist/index.js.map +++ b/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,wCAAwC;AACxC,wCAAwC;AACxC,+DAA4D;AAApD,sDAAA,oBAAoB,CAAA;AAC5B,2DAAwD;AAAhD,kDAAA,kBAAkB,CAAA;AAC1B,2CAAwC;AAAhC,kCAAA,UAAU,CAAA;AAClB,qCAAiD;AAAzC,4BAAA,OAAO,CAAA;AAAE,kCAAA,aAAa,CAAA"} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,wCAAwC;AACxC,wCAAwC;AACxC,+DAA6D;AAApD,sDAAA,oBAAoB,CAAA;AAC7B,2DAAyD;AAAhD,kDAAA,kBAAkB,CAAA;AAC3B,+DAA6D;AAApD,sDAAA,oBAAoB,CAAA;AAE7B,2CAAyC;AAAhC,kCAAA,UAAU,CAAA;AACnB,qCAAkD;AAAzC,4BAAA,OAAO,CAAA;AAAE,kCAAA,aAAa,CAAA"} \ No newline at end of file diff --git a/dist/readConfig.js b/dist/readConfig.js index a25ddb8..0ad37a3 100644 --- a/dist/readConfig.js +++ b/dist/readConfig.js @@ -6,7 +6,8 @@ exports.readConfig = () => { const dir = process.cwd(); const defaultOptions = { featuresDir: path.resolve(dir, 'features'), - stepDefinitionsDir: path.resolve(dir, 'features', 'step_definitions') + stepDefinitionsDir: path.resolve(dir, 'features', 'step_definitions'), + resultsDir: path.resolve(dir, 'results'), }; const options = require(path.resolve(dir, '.testrail-sync.js')); if (options.featuresDir) { diff --git a/dist/readConfig.js.map b/dist/readConfig.js.map index 9f1227f..a79cdad 100644 --- a/dist/readConfig.js.map +++ b/dist/readConfig.js.map @@ -1 +1 @@ -{"version":3,"file":"readConfig.js","sourceRoot":"","sources":["../src/readConfig.ts"],"names":[],"mappings":";;AAAA,6BAA6B;AAC7B,4BAA4B;AAGf,QAAA,UAAU,GAAG,GAAgC,EAAE;IACxD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAE1B,MAAM,cAAc,GAAG;QACnB,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC;QAC1C,kBAAkB,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,UAAU,EAAE,kBAAkB,CAAC;KACxE,CAAC;IAEF,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAEhE,IAAI,OAAO,CAAC,WAAW,EAAE;QACrB,cAAc,CAAC,kBAAkB,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC;KAC7F;IAED,OAAsC,CAAC,CAAC,YAAY,CAAC,OAAO,EAAE,cAAc,CAAE,CAAC;AACnF,CAAC,CAAC"} \ No newline at end of file +{"version":3,"file":"readConfig.js","sourceRoot":"","sources":["../src/readConfig.ts"],"names":[],"mappings":";;AAAA,6BAA4B;AAC5B,4BAA2B;AAGd,QAAA,UAAU,GAAG,GAAgC,EAAE;IAC1D,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAA;IAEzB,MAAM,cAAc,GAAG;QACrB,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC;QAC1C,kBAAkB,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,UAAU,EAAE,kBAAkB,CAAC;QACrE,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC;KACzC,CAAA;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,mBAAmB,CAAC,CAAC,CAAA;IAE/D,IAAI,OAAO,CAAC,WAAW,EAAE;QACvB,cAAc,CAAC,kBAAkB,GAAG,IAAI,CAAC,OAAO,CAC9C,OAAO,CAAC,WAAW,EACnB,kBAAkB,CACnB,CAAA;KACF;IAED,OAAoC,CAAC,CAAC,YAAY,CAAC,OAAO,EAAE,cAAc,CAAC,CAAA;AAC7E,CAAC,CAAA"} \ No newline at end of file diff --git a/index.d.ts b/index.d.ts index 91c56c0..ff1a951 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,56 +1,57 @@ interface TestrailOptions { testrail: { - host: string; - user: string; - password: string; + host: string + user: string + password: string filters: { - plan_id: number; - run_id?: number; - custom_status?: [number]; - }; + plan_id: number + run_id?: number + custom_status?: [number] + } verifyFilters?: { - custom_status?: [number]; + custom_status?: [number] } - }; + } } export interface ScenarioSynchronizerOptions extends TestrailOptions { - featuresDir: string; - stepDefinitionsDir: string; + featuresDir: string + resultsDir: string + stepDefinitionsDir: string overwrite?: { - local?: boolean | string; - remote?: boolean | string; - }; - stepDefinitionsTemplate?: string; - stepDefinitionsStringPatterns?: boolean; - stepDefinitionsExpressions?: boolean; - indent?: string; - silent?: boolean; + local?: boolean | string + remote?: boolean | string + } + stepDefinitionsTemplate?: string + stepDefinitionsStringPatterns?: boolean + stepDefinitionsExpressions?: boolean + indent?: string + silent?: boolean directoryStructure?: { - type?: string; - skipRootFolder?: number; - }; - verify?: boolean; - findUnused?: boolean; - pushResults?: boolean; - debug?: boolean; + type?: string + skipRootFolder?: number + } + verify?: boolean + findUnused?: boolean + pushResults?: boolean + debug?: boolean newTestCase?: { - section_id: number; - [key: string]: any; - }; + section_id: number + [key: string]: any + } } export class ScenarioSynchronizer { - constructor(); - synchronize(options: ScenarioSynchronizerOptions, callback: Function): void; + constructor() + synchronize(options: ScenarioSynchronizerOptions, callback: Function): void } export class ResultSynchronizer { - constructor(options: ScenarioSynchronizerOptions); - saveTestResult(scenario: any, callback: Function): void; - pushTestResults(callback: Function): void; + constructor(options: ScenarioSynchronizerOptions) + saveTestResult(scenario: any, callback: Function): void + pushTestResults(callback: Function): void } -export function readConfig(): ScenarioSynchronizerOptions; +export function readConfig(): ScenarioSynchronizerOptions -export function install(cucumber: any): void; +export function install(cucumber: any): void diff --git a/src/CucumberReportParser.ts b/src/CucumberReportParser.ts new file mode 100755 index 0000000..7bee2ab --- /dev/null +++ b/src/CucumberReportParser.ts @@ -0,0 +1,40 @@ +import { Scenario, TestCaseReport, Step } from './index'; + +export class CucumberReportParser { + protected report: any[]; + protected scenarios: Scenario[]; + + public parseReport(report: TestCaseReport[]): Scenario[] { + this.report = report; + this.scenarios = []; + report.forEach((result: any) => { + this.parseTestCases(result.elements); + }); + return this.scenarios; + } + + protected parseTestCases(testCases: TestCaseReport[]): void { + testCases.forEach((testCase: TestCaseReport) => { + const error = this.parseTestCase(testCase); + const scenario = { + tags: [testCase.tags[0].name], + isPending: false, + isUndefined: false, + isSkipped: false, + isSuccessful: error === null, + exception: error + }; + this.scenarios.push(scenario); + }); + } + + protected parseTestCase(testCase: TestCaseReport): Error { + let error = null; + testCase.steps.forEach((step: Step) => { + if (step.result.status !== 'passed') { + error = `status[${step.result.status}] step[${step.name}]`; + } + }); + return error; + } +} diff --git a/src/GherkinFormatter.ts b/src/GherkinFormatter.ts index bae911c..04b94ac 100644 --- a/src/GherkinFormatter.ts +++ b/src/GherkinFormatter.ts @@ -32,14 +32,23 @@ export class GherkinFormatter { } public getGherkinFromTestcase(testcase: any): string { + let gherkinTest = ''; + if (testcase.custom_preconds && testcase.custom_preconds.length > 0) { + gherkinTest += testcase.custom_preconds + '\n'; + } + if (testcase.custom_gherkin && testcase.custom_gherkin.length > 0) { - return testcase.custom_gherkin; + gherkinTest += testcase.custom_gherkin; } else if (testcase.custom_steps && testcase.custom_steps.length > 0) { - return testcase.custom_steps; + gherkinTest += testcase.custom_steps; } else if (testcase.custom_steps_separated && testcase.custom_steps_separated.length > 0) { - return testcase.custom_steps_separated.map((s: any) => s.content).join('\n'); + gherkinTest += testcase.custom_steps_separated.map((s) => s.content).join('\n'); } - return ''; + if (testcase.custom_expected && testcase.custom_expected.length > 0) { + gherkinTest += '\n' + testcase.custom_expected + '\n'; + } + + return gherkinTest; } /** diff --git a/src/bin/push-test-result-file.ts b/src/bin/push-test-result-file.ts new file mode 100755 index 0000000..521be73 --- /dev/null +++ b/src/bin/push-test-result-file.ts @@ -0,0 +1,47 @@ +#!/usr/bin/env node +import * as program from 'commander'; +import * as path from 'path'; +import { ResultSynchronizer, readConfig, CucumberReportParser } from '../index'; +import * as fs from 'fs'; + +const parser = new CucumberReportParser(); + +program.option('--file ', 'filename in results directory').parse(process.argv); + +const error = (s: string): void => { + program.outputHelp(); + console.log(); + console.log('Error: ' + s); + process.exit(1); +}; + +if (!( program).file || [0, NaN].indexOf(( program).file) !== -1) { + error(' is required and must be a string'); +} +const config = readConfig(); +config.pushResults = true; + +const resultFile = String(( program).file); + +let results; +try { + const jsonString = fs.readFileSync(path.resolve(config.resultsDir, resultFile)); + results = JSON.parse(String(jsonString)); +} catch (err) { + error(` error reading file[${path.resolve(config.resultsDir, resultFile)}] exception[${err}]`); +} + +if (!Array.isArray(results)) { + error(` wrong cucumber format result file ${path.resolve(config.resultsDir, resultFile)}`); +} + +const scenarios = parser.parseReport(results); + +const sync = new ResultSynchronizer(config); +const savePromises = []; +for (const scenario of scenarios) { + savePromises.push(sync.saveTestResult(scenario)); +} +Promise.all(savePromises) + .then(() => sync.readRemoteTestRuns().then(() => sync.pushTestResults().then(() => console.log('sync done')))) + .catch(e => error(e)); diff --git a/src/bin/push-test-result.ts b/src/bin/push-test-result.ts index bb95a77..674ccb1 100644 --- a/src/bin/push-test-result.ts +++ b/src/bin/push-test-result.ts @@ -1,6 +1,6 @@ #!/usr/bin/env node import * as program from 'commander'; -import {ResultSynchronizer, readConfig} from '../index'; +import { ResultSynchronizer, readConfig } from '../index'; program .option('--id ', 'testcase id') diff --git a/src/index.ts b/src/index.ts index d14bd5d..6f91b41 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,15 +1,42 @@ // tslint:disable-next-line:no-reference /// -export {ScenarioSynchronizer} from './ScenarioSynchronizer'; -export {ResultSynchronizer} from './ResultSynchronizer'; -export {readConfig} from './readConfig'; -export {install, legacyInstall} from './install'; +export { ScenarioSynchronizer } from './ScenarioSynchronizer'; +export { ResultSynchronizer } from './ResultSynchronizer'; +export { CucumberReportParser } from './CucumberReportParser'; + +export { readConfig } from './readConfig'; +export { install, legacyInstall } from './install'; export interface Scenario { - tags: string[]; - isPending: boolean; - isUndefined: boolean; - isSkipped: boolean; - isSuccessful: boolean; - exception: Error; + tags: string[]; + isPending: boolean; + isUndefined: boolean; + isSkipped: boolean; + isSuccessful: boolean; + exception: Error; +} + +export interface TestCaseReport { + id: Number; + name: string; + tags: Tag[]; + type: string; + steps: Step[]; +} + +export interface Step { + keyword: string; + line: Number; + name: string; + result: StepResult; +} + +export interface StepResult { + status: string; + duration: Number; +} + +export interface Tag { + line: Number; + name: String; } diff --git a/src/install.ts b/src/install.ts index c46ab00..f36bf11 100644 --- a/src/install.ts +++ b/src/install.ts @@ -1,6 +1,6 @@ -import {readConfig} from './readConfig'; -import {ResultSynchronizer} from './ResultSynchronizer'; -import {Scenario} from './index'; +import { readConfig } from './readConfig'; +import { ResultSynchronizer } from './ResultSynchronizer'; +import { Scenario } from './index'; // tslint:disable-next-line:variable-name const installHandlers = (registerHandler: any, After: any): void => { diff --git a/src/readConfig.ts b/src/readConfig.ts index 7050323..d0c02c6 100644 --- a/src/readConfig.ts +++ b/src/readConfig.ts @@ -1,20 +1,24 @@ import * as path from 'path'; import * as _ from 'lodash'; -import {ScenarioSynchronizerOptions} from '../index.d'; +import { ScenarioSynchronizerOptions } from '../index.d'; export const readConfig = (): ScenarioSynchronizerOptions => { - const dir = process.cwd(); + const dir = process.cwd(); - const defaultOptions = { - featuresDir: path.resolve(dir, 'features'), - stepDefinitionsDir: path.resolve(dir, 'features', 'step_definitions') - }; + const defaultOptions = { + featuresDir: path.resolve(dir, 'features'), + stepDefinitionsDir: path.resolve(dir, 'features', 'step_definitions'), + resultsDir: path.resolve(dir, 'results') + }; - const options = require(path.resolve(dir, '.testrail-sync.js')); + const options = require(path.resolve(dir, '.testrail-sync.js')); - if (options.featuresDir) { - defaultOptions.stepDefinitionsDir = path.resolve(options.featuresDir, 'step_definitions'); - } + if (options.featuresDir) { + defaultOptions.stepDefinitionsDir = path.resolve( + options.featuresDir, + 'step_definitions' + ); + } - return ( _.defaultsDeep(options, defaultOptions)); + return _.defaultsDeep(options, defaultOptions); }; diff --git a/tests/unit/cucumberReportFiles-fixtures.ts b/tests/unit/cucumberReportFiles-fixtures.ts new file mode 100755 index 0000000..6c35f4e --- /dev/null +++ b/tests/unit/cucumberReportFiles-fixtures.ts @@ -0,0 +1,128 @@ +export const fixtures = { + good: [ + { + keyword: 'Feature', + name: 'Test Cases', + line: 1, + id: 'test-cases', + tags: [], + uri: 'login.feature', + elements: [ + { + id: 'test-cases;login', + keyword: 'Scenario', + line: 3, + name: 'Login', + tags: [ + { + name: '@tcid:77980', + line: 2 + } + ], + type: 'scenario', + steps: [ + { + arguments: [], + keyword: 'Given ', + line: 4, + name: 'I am on my page', + result: { + status: 'passed', + duration: 8021000000 + } + }, + { + arguments: [], + keyword: 'When ', + line: 5, + name: 'I log as a valid user', + result: { + status: 'passed', + duration: 9687000000 + } + }, + { + arguments: [], + keyword: 'Then ', + line: 6, + name: 'I see the News Line', + result: { + status: 'passed', + duration: 7555000000 + } + } + ] + } + ] + } + ], + emptyElements: [ + { + keyword: 'Feature', + name: 'Test Cases', + line: 1, + id: 'test-cases', + tags: [], + uri: 'login.feature', + elements: [] + } + ], + empty: [], + errorOnLastStep: [ + { + keyword: 'Feature', + name: 'Test Cases', + line: 1, + id: 'test-cases', + tags: [], + uri: 'login.feature', + elements: [ + { + id: 'test-cases;login', + keyword: 'Scenario', + line: 3, + name: 'Login', + tags: [ + { + name: '@tcid:77980', + line: 2 + } + ], + type: 'scenario', + steps: [ + { + arguments: [], + keyword: 'Given ', + line: 4, + name: 'I am on my page', + result: { + status: 'passed', + duration: 8021000000 + } + }, + { + arguments: [], + keyword: 'When ', + line: 5, + name: 'I log as a valid user', + result: { + status: 'passed', + duration: 9687000000 + } + }, + { + arguments: [], + keyword: 'Then ', + line: 6, + name: 'I see the News Line', + result: { + status: 'failed', + duration: 7555000000 + } + } + ] + } + ] + } + ] +}; diff --git a/tests/unit/cucumberReportParser.ts b/tests/unit/cucumberReportParser.ts new file mode 100755 index 0000000..88db6a0 --- /dev/null +++ b/tests/unit/cucumberReportParser.ts @@ -0,0 +1,43 @@ +import { expect } from 'chai'; +import { CucumberReportParser } from '../../src/index'; +import * as reportmock from './cucumberReportFiles-fixtures'; + +describe('Test cucumber report parser', () => { + it('return scenario when report file is ok', (done: Function) => { + const parser = new CucumberReportParser(); + const result = parser.parseReport(reportmock.fixtures.good); + expect(Object.keys(result)).to.have.lengthOf(1); + expect(result[0].isSuccessful).to.equal(true); + expect(result[0].exception).to.equal(null); + expect(result[0]).to.have.property('tags'); + expect(result[0]).to.have.property('isSuccessful'); + expect(result[0].tags[0]).to.equal('@tcid:77980'); + done(); + }); + + it('return nothing when report file has no elements empty', (done: Function) => { + const parser = new CucumberReportParser(); + const result = parser.parseReport(reportmock.fixtures.emptyElements); + expect(Object.keys(result)).to.have.lengthOf(0); + done(); + }); + + it('return nothing when report file is empty', (done: Function) => { + const parser = new CucumberReportParser(); + const result = parser.parseReport(reportmock.fixtures.empty); + expect(Object.keys(result)).to.have.lengthOf(0); + done(); + }); + + it('return nothing when report file has wrong format', (done: Function) => { + const parser = new CucumberReportParser(); + const result = parser.parseReport(reportmock.fixtures.errorOnLastStep); + expect(Object.keys(result)).to.have.lengthOf(1); + expect(result[0].isSuccessful).to.equal(false); + expect(result[0].exception).to.be.equal('status[failed] step[I see the News Line]'); + expect(result[0]).to.have.property('tags'); + expect(result[0]).to.have.property('isSuccessful'); + expect(result[0].tags[0]).to.equal('@tcid:77980'); + done(); + }); +});