From 247578fa982ab12703506e6e973cd51914759092 Mon Sep 17 00:00:00 2001 From: dropdbs <61979544+dropdbs@users.noreply.github.com> Date: Fri, 13 Mar 2020 18:09:36 +0100 Subject: [PATCH 1/9] add support for expected and preconds --- src/GherkinFormatter.ts | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/GherkinFormatter.ts b/src/GherkinFormatter.ts index bae911c..14ae561 100644 --- a/src/GherkinFormatter.ts +++ b/src/GherkinFormatter.ts @@ -32,14 +32,25 @@ 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; - } else if (testcase.custom_steps && testcase.custom_steps.length > 0) { - return 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_gherkin; + } + else if (testcase.custom_steps && testcase.custom_steps.length > 0) { + gherkinTest+= testcase.custom_steps; } - return ''; + else if (testcase.custom_steps_separated && testcase.custom_steps_separated.length > 0) { + gherkinTest+= testcase.custom_steps_separated.map((s) => s.content).join('\n'); + } + if (testcase.custom_expected && testcase.custom_expected.length > 0) { + gherkinTest+= '\n'+testcase.custom_expected+'\n'; + } + + return gherkinTest; } /** From db56d8efe8459d0ffa3c4066dce3bcd918a4f964 Mon Sep 17 00:00:00 2001 From: "thomas.choquet" Date: Mon, 16 Mar 2020 18:56:48 +0100 Subject: [PATCH 2/9] add sync by report file --- index.d.ts | 73 ++++++------ src/CucumberReportParser.ts | 41 +++++++ src/bin/push-test-result-file.ts | 62 ++++++++++ src/index.ts | 48 ++++++-- src/readConfig.ts | 32 +++--- tests/unit/cucumberReportFiles-fixtures.ts | 128 +++++++++++++++++++++ tests/unit/cucumberReportParser.ts | 45 ++++++++ 7 files changed, 369 insertions(+), 60 deletions(-) create mode 100755 src/CucumberReportParser.ts create mode 100755 src/bin/push-test-result-file.ts create mode 100755 tests/unit/cucumberReportFiles-fixtures.ts create mode 100755 tests/unit/cucumberReportParser.ts 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..60c43de --- /dev/null +++ b/src/CucumberReportParser.ts @@ -0,0 +1,41 @@ +import { Scenario, TestCaseReport, Step } from './index' + +export class CucumberReportParser { + protected report: Array + protected scenarios: Array + + public parseReport(report: Array): Array { + this.report = report + this.scenarios = [] + report.forEach((result: any) => { + let testCases = result.elements + this.parseTestCases(testCases) + }) + return this.scenarios + } + + protected parseTestCases(testCases: Array): any { + testCases.forEach((testCase: TestCaseReport) => { + 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) + }) + } + + protected parseTestCase(testCase: any): 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/bin/push-test-result-file.ts b/src/bin/push-test-result-file.ts new file mode 100755 index 0000000..6006e58 --- /dev/null +++ b/src/bin/push-test-result-file.ts @@ -0,0 +1,62 @@ +#!/usr/bin/env node +import * as program from 'commander' +import * as path from 'path' +import { ResultSynchronizer, readConfig, CucumberReportParser } from '../index' + +let 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') +} +let config = 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 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)) diff --git a/src/index.ts b/src/index.ts index d14bd5d..012e560 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,15 +1,43 @@ // 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: Array + type: string + steps: Array +} + +export interface Step { + arguments: Array + 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/readConfig.ts b/src/readConfig.ts index 7050323..dd7b05c 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 * as path from 'path' +import * as _ from 'lodash' +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..cf76725 --- /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..5a17d65 --- /dev/null +++ b/tests/unit/cucumberReportParser.ts @@ -0,0 +1,45 @@ +import { expect } from 'chai' +import { CucumberReportParser, Scenario } 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() + let result = parser.parseReport(reportmock.fixtures.good) + expect(Object.keys(result)).to.have.lengthOf(1) + expect(result[0].isSuccessful).to.be.true + expect(result[0].exception).to.be.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() + let 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() + let 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() + let result = parser.parseReport(reportmock.fixtures.errorOnLastStep) + expect(Object.keys(result)).to.have.lengthOf(1) + expect(result[0].isSuccessful).to.be.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() + }) +}) From 05eaa4cd0482fdc0afb9393d1d0a7d657393e8fb Mon Sep 17 00:00:00 2001 From: "thomas.choquet" Date: Tue, 17 Mar 2020 11:02:23 +0100 Subject: [PATCH 3/9] add dist change --- dist/CucumberReportParser.js | 38 +++++++++++++++++++++++ dist/CucumberReportParser.js.map | 1 + dist/bin/push-test-result-file.js | 44 +++++++++++++++++++++++++++ dist/bin/push-test-result-file.js.map | 1 + dist/index.js | 2 ++ dist/index.js.map | 2 +- dist/readConfig.js | 3 +- dist/readConfig.js.map | 2 +- 8 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 dist/CucumberReportParser.js create mode 100644 dist/CucumberReportParser.js.map create mode 100644 dist/bin/push-test-result-file.js create mode 100644 dist/bin/push-test-result-file.js.map 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 From 2535b4fbbb169c264d41b989ab8a8dbacf725d98 Mon Sep 17 00:00:00 2001 From: dropdbs Date: Tue, 17 Mar 2020 12:02:19 +0100 Subject: [PATCH 4/9] fix tslint --- src/CucumberReportParser.ts | 69 +++++++++--------- src/GherkinFormatter.ts | 16 ++--- src/bin/push-test-result-file.ts | 84 +++++++++++----------- src/index.ts | 50 ++++++------- tests/unit/cucumberReportFiles-fixtures.ts | 60 ++++++++-------- tests/unit/cucumberReportParser.ts | 80 ++++++++++----------- 6 files changed, 178 insertions(+), 181 deletions(-) diff --git a/src/CucumberReportParser.ts b/src/CucumberReportParser.ts index 60c43de..a893085 100755 --- a/src/CucumberReportParser.ts +++ b/src/CucumberReportParser.ts @@ -1,41 +1,40 @@ -import { Scenario, TestCaseReport, Step } from './index' +import { Scenario, TestCaseReport, Step } from './index'; export class CucumberReportParser { - protected report: Array - protected scenarios: Array + protected report: Array; + protected scenarios: Array; - public parseReport(report: Array): Array { - this.report = report - this.scenarios = [] - report.forEach((result: any) => { - let testCases = result.elements - this.parseTestCases(testCases) - }) - return this.scenarios - } + public parseReport(report: Array): Array { + this.report = report; + this.scenarios = []; + report.forEach((result: any) => { + this.parseTestCases(result.elements); + }); + return this.scenarios; + } - protected parseTestCases(testCases: Array): any { - testCases.forEach((testCase: TestCaseReport) => { - 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) - }) - } + protected parseTestCases(testCases: Array): any { + 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: any): Error { - let error = null - testCase.steps.forEach((step: Step) => { - if (step.result.status !== 'passed') { - error = `status[${step.result.status}] step[${step.name}]` - } - }) - return error - } + protected parseTestCase(testCase: any): 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 14ae561..04b94ac 100644 --- a/src/GherkinFormatter.ts +++ b/src/GherkinFormatter.ts @@ -34,20 +34,18 @@ export class GherkinFormatter { public getGherkinFromTestcase(testcase: any): string { let gherkinTest = ''; if (testcase.custom_preconds && testcase.custom_preconds.length > 0) { - gherkinTest+= testcase.custom_preconds+'\n'; + gherkinTest += testcase.custom_preconds + '\n'; } if (testcase.custom_gherkin && testcase.custom_gherkin.length > 0) { - gherkinTest+= testcase.custom_gherkin; - } - else if (testcase.custom_steps && testcase.custom_steps.length > 0) { - gherkinTest+= testcase.custom_steps; - } - else if (testcase.custom_steps_separated && testcase.custom_steps_separated.length > 0) { - gherkinTest+= testcase.custom_steps_separated.map((s) => s.content).join('\n'); + gherkinTest += testcase.custom_gherkin; + } else if (testcase.custom_steps && testcase.custom_steps.length > 0) { + gherkinTest += testcase.custom_steps; + } else if (testcase.custom_steps_separated && testcase.custom_steps_separated.length > 0) { + gherkinTest += testcase.custom_steps_separated.map((s) => s.content).join('\n'); } if (testcase.custom_expected && testcase.custom_expected.length > 0) { - gherkinTest+= '\n'+testcase.custom_expected+'\n'; + 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 index 6006e58..ae06583 100755 --- a/src/bin/push-test-result-file.ts +++ b/src/bin/push-test-result-file.ts @@ -1,62 +1,62 @@ #!/usr/bin/env node -import * as program from 'commander' -import * as path from 'path' -import { ResultSynchronizer, readConfig, CucumberReportParser } from '../index' +import * as program from 'commander'; +import * as path from 'path'; +import { ResultSynchronizer, readConfig, CucumberReportParser } from '../index'; -let parser = new CucumberReportParser() +const parser = new CucumberReportParser(); program - .option('--file ', 'filename in results directory') - .parse(process.argv) + .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) + 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; -if (!(program).file || [0, NaN].indexOf((program).file) !== -1) { - error(' is required and must be a string') -} -let config = readConfig() -config.pushResults = true - -const resultFile = String((program).file) -let results +const resultFile = String(( program).file); +let results; try { - results = require(path.resolve(config.resultsDir, resultFile)) + results = require(path.resolve(config.resultsDir, resultFile)); } catch (e) { - error( - ` error reading file[${path.resolve( - config.resultsDir, - resultFile - )}] exception[${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 - )}` - ) + error( + ` wrong cucumber format result file ${path.resolve( + config.resultsDir, + resultFile + )}` + ); } -const scenarios = parser.parseReport(results) +const scenarios = parser.parseReport(results); -const sync = new ResultSynchronizer(config) -const savePromises = [] +const sync = new ResultSynchronizer(config); +const savePromises = []; for (const scenario of scenarios) { - savePromises.push(sync.saveTestResult(scenario)) + savePromises.push(sync.saveTestResult(scenario)); } Promise.all(savePromises) - .then(() => - sync.readRemoteTestRuns().then(() => - sync.pushTestResults().then(function() { - console.log(`sync done`) - }) + .then(() => + sync.readRemoteTestRuns().then(() => + sync.pushTestResults().then(function() { + console.log(`sync done`); + }) + ) ) - ) - .catch(e => error(e)) + .catch(e => error(e)); diff --git a/src/index.ts b/src/index.ts index 012e560..d2b3a5e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,43 +1,43 @@ // tslint:disable-next-line:no-reference /// -export { ScenarioSynchronizer } from './ScenarioSynchronizer' -export { ResultSynchronizer } from './ResultSynchronizer' -export { CucumberReportParser } from './CucumberReportParser' +export { ScenarioSynchronizer } from './ScenarioSynchronizer'; +export { ResultSynchronizer } from './ResultSynchronizer'; +export { CucumberReportParser } from './CucumberReportParser'; -export { readConfig } from './readConfig' -export { install, legacyInstall } from './install' +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: Array - type: string - steps: Array + id: Number; + name: string; + tags: Array; + type: string; + steps: Array; } export interface Step { - arguments: Array - keyword: string - line: Number - name: string - result: StepResult + arguments: Array; + keyword: string; + line: Number; + name: string; + result: StepResult; } export interface StepResult { - status: string - duration: Number + status: string; + duration: Number; } export interface Tag { - line: Number - name: String + line: Number; + name: String; } diff --git a/tests/unit/cucumberReportFiles-fixtures.ts b/tests/unit/cucumberReportFiles-fixtures.ts index cf76725..6c35f4e 100755 --- a/tests/unit/cucumberReportFiles-fixtures.ts +++ b/tests/unit/cucumberReportFiles-fixtures.ts @@ -16,8 +16,8 @@ export const fixtures = { tags: [ { name: '@tcid:77980', - line: 2, - }, + line: 2 + } ], type: 'scenario', steps: [ @@ -28,8 +28,8 @@ export const fixtures = { name: 'I am on my page', result: { status: 'passed', - duration: 8021000000, - }, + duration: 8021000000 + } }, { arguments: [], @@ -38,8 +38,8 @@ export const fixtures = { name: 'I log as a valid user', result: { status: 'passed', - duration: 9687000000, - }, + duration: 9687000000 + } }, { arguments: [], @@ -48,13 +48,13 @@ export const fixtures = { name: 'I see the News Line', result: { status: 'passed', - duration: 7555000000, - }, - }, - ], - }, - ], - }, + duration: 7555000000 + } + } + ] + } + ] + } ], emptyElements: [ { @@ -64,8 +64,8 @@ export const fixtures = { id: 'test-cases', tags: [], uri: 'login.feature', - elements: [], - }, + elements: [] + } ], empty: [], errorOnLastStep: [ @@ -85,8 +85,8 @@ export const fixtures = { tags: [ { name: '@tcid:77980', - line: 2, - }, + line: 2 + } ], type: 'scenario', steps: [ @@ -97,8 +97,8 @@ export const fixtures = { name: 'I am on my page', result: { status: 'passed', - duration: 8021000000, - }, + duration: 8021000000 + } }, { arguments: [], @@ -107,8 +107,8 @@ export const fixtures = { name: 'I log as a valid user', result: { status: 'passed', - duration: 9687000000, - }, + duration: 9687000000 + } }, { arguments: [], @@ -117,12 +117,12 @@ export const fixtures = { name: 'I see the News Line', result: { status: 'failed', - duration: 7555000000, - }, - }, - ], - }, - ], - }, - ], -} + duration: 7555000000 + } + } + ] + } + ] + } + ] +}; diff --git a/tests/unit/cucumberReportParser.ts b/tests/unit/cucumberReportParser.ts index 5a17d65..a7ad069 100755 --- a/tests/unit/cucumberReportParser.ts +++ b/tests/unit/cucumberReportParser.ts @@ -1,45 +1,45 @@ -import { expect } from 'chai' -import { CucumberReportParser, Scenario } from '../../src/index' -import * as reportmock from './cucumberReportFiles-fixtures' +import { expect } from 'chai'; +import { CucumberReportParser, Scenario } 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() - let result = parser.parseReport(reportmock.fixtures.good) - expect(Object.keys(result)).to.have.lengthOf(1) - expect(result[0].isSuccessful).to.be.true - expect(result[0].exception).to.be.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 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() - let result = parser.parseReport(reportmock.fixtures.emptyElements) - expect(Object.keys(result)).to.have.lengthOf(0) - 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() - let result = parser.parseReport(reportmock.fixtures.empty) - 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() - let result = parser.parseReport(reportmock.fixtures.errorOnLastStep) - expect(Object.keys(result)).to.have.lengthOf(1) - expect(result[0].isSuccessful).to.be.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() - }) -}) + 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(); + }); +}); From e22d3ac21c1d5b27661ce4762cbb736463d2be0c Mon Sep 17 00:00:00 2001 From: dropdbs Date: Tue, 17 Mar 2020 15:24:16 +0100 Subject: [PATCH 5/9] fix lint --- src/bin/push-test-result.ts | 2 +- src/install.ts | 6 +-- src/readConfig.ts | 20 ++++----- tests/unit/cucumberReportParser.ts | 72 +++++++++++++++--------------- 4 files changed, 49 insertions(+), 51 deletions(-) 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/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 dd7b05c..d0c02c6 100644 --- a/src/readConfig.ts +++ b/src/readConfig.ts @@ -1,24 +1,24 @@ -import * as path from 'path' -import * as _ from 'lodash' -import { ScenarioSynchronizerOptions } from '../index.d' +import * as path from 'path'; +import * as _ from 'lodash'; +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'), - resultsDir: path.resolve(dir, 'results'), - } + 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' - ) + ); } - return _.defaultsDeep(options, defaultOptions) -} + return _.defaultsDeep(options, defaultOptions); +}; diff --git a/tests/unit/cucumberReportParser.ts b/tests/unit/cucumberReportParser.ts index a7ad069..88db6a0 100755 --- a/tests/unit/cucumberReportParser.ts +++ b/tests/unit/cucumberReportParser.ts @@ -1,45 +1,43 @@ import { expect } from 'chai'; -import { CucumberReportParser, Scenario } from '../../src/index'; +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 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 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 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(); - }); + 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(); + }); }); From 2596a0f37b23b9f017a2119ae3e64b31f8ca354b Mon Sep 17 00:00:00 2001 From: dropdbs Date: Tue, 17 Mar 2020 15:33:09 +0100 Subject: [PATCH 6/9] fix lint --- src/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index d2b3a5e..897875f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -19,13 +19,13 @@ export interface Scenario { export interface TestCaseReport { id: Number; name: string; - tags: Array; + tags: Tag[]; type: string; steps: Array; } export interface Step { - arguments: Array; + arguments: any[]; keyword: string; line: Number; name: string; From 8137e0e342d522951ba1f8872f83554df12ae9ec Mon Sep 17 00:00:00 2001 From: dropdbs Date: Tue, 17 Mar 2020 15:34:46 +0100 Subject: [PATCH 7/9] fix lint --- src/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 897875f..bda2424 100644 --- a/src/index.ts +++ b/src/index.ts @@ -25,7 +25,6 @@ export interface TestCaseReport { } export interface Step { - arguments: any[]; keyword: string; line: Number; name: string; From aac8b8b28770158faba146d20c4b76f1c990d9d7 Mon Sep 17 00:00:00 2001 From: dropdbs Date: Tue, 17 Mar 2020 16:15:51 +0100 Subject: [PATCH 8/9] fix lint --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index bda2424..6f91b41 100644 --- a/src/index.ts +++ b/src/index.ts @@ -21,7 +21,7 @@ export interface TestCaseReport { name: string; tags: Tag[]; type: string; - steps: Array; + steps: Step[]; } export interface Step { From 597ca12a9332fd3366acae862bece80dfa758fd7 Mon Sep 17 00:00:00 2001 From: dropdbs Date: Tue, 17 Mar 2020 18:31:45 +0100 Subject: [PATCH 9/9] update lint --- src/CucumberReportParser.ts | 66 ++++++++++++++++---------------- src/bin/push-test-result-file.ts | 47 ++++++++--------------- 2 files changed, 49 insertions(+), 64 deletions(-) diff --git a/src/CucumberReportParser.ts b/src/CucumberReportParser.ts index a893085..7bee2ab 100755 --- a/src/CucumberReportParser.ts +++ b/src/CucumberReportParser.ts @@ -1,40 +1,40 @@ import { Scenario, TestCaseReport, Step } from './index'; export class CucumberReportParser { - protected report: Array; - protected scenarios: Array; + protected report: any[]; + protected scenarios: Scenario[]; - public parseReport(report: Array): Array { - this.report = report; - this.scenarios = []; - report.forEach((result: any) => { - this.parseTestCases(result.elements); - }); - return this.scenarios; - } + public parseReport(report: TestCaseReport[]): Scenario[] { + this.report = report; + this.scenarios = []; + report.forEach((result: any) => { + this.parseTestCases(result.elements); + }); + return this.scenarios; + } - protected parseTestCases(testCases: Array): any { - 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 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: any): Error { - let error = null; - testCase.steps.forEach((step: Step) => { - if (step.result.status !== 'passed') { - error = `status[${step.result.status}] step[${step.name}]`; - } - }); - return error; - } + 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/bin/push-test-result-file.ts b/src/bin/push-test-result-file.ts index ae06583..521be73 100755 --- a/src/bin/push-test-result-file.ts +++ b/src/bin/push-test-result-file.ts @@ -2,46 +2,37 @@ 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); +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); + 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'); + error(' is required and must be a string'); } const config = 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}]` - ); + 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 - )}` - ); + error(` wrong cucumber format result file ${path.resolve(config.resultsDir, resultFile)}`); } const scenarios = parser.parseReport(results); @@ -49,14 +40,8 @@ const scenarios = parser.parseReport(results); const sync = new ResultSynchronizer(config); const savePromises = []; for (const scenario of scenarios) { - savePromises.push(sync.saveTestResult(scenario)); + savePromises.push(sync.saveTestResult(scenario)); } Promise.all(savePromises) - .then(() => - sync.readRemoteTestRuns().then(() => - sync.pushTestResults().then(function() { - console.log(`sync done`); - }) - ) - ) - .catch(e => error(e)); + .then(() => sync.readRemoteTestRuns().then(() => sync.pushTestResults().then(() => console.log('sync done')))) + .catch(e => error(e));