Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add file import report to testrail #23

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions dist/CucumberReportParser.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions dist/CucumberReportParser.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 44 additions & 0 deletions dist/bin/push-test-result-file.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions dist/bin/push-test-result-file.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/index.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion dist/readConfig.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/readConfig.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

73 changes: 37 additions & 36 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -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
40 changes: 40 additions & 0 deletions src/CucumberReportParser.ts
Original file line number Diff line number Diff line change
@@ -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 = <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;
}
}
17 changes: 13 additions & 4 deletions src/GherkinFormatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

/**
Expand Down
47 changes: 47 additions & 0 deletions src/bin/push-test-result-file.ts
Original file line number Diff line number Diff line change
@@ -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 <String>', 'filename in results directory').parse(process.argv);

const error = (s: string): void => {
program.outputHelp();
console.log();
console.log('Error: ' + s);
process.exit(1);
};

if (!(<any> program).file || [0, NaN].indexOf((<any> program).file) !== -1) {
error('<testcase file> is required and must be a string');
}
const config = readConfig();
config.pushResults = true;

const resultFile = String((<any> program).file);

let results;
try {
const jsonString = fs.readFileSync(path.resolve(config.resultsDir, resultFile));
results = JSON.parse(String(jsonString));
} catch (err) {
error(`<testcase file> error reading file[${path.resolve(config.resultsDir, resultFile)}] exception[${err}]`);
}

if (!Array.isArray(results)) {
error(`<testcase file> 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));
2 changes: 1 addition & 1 deletion src/bin/push-test-result.ts
Original file line number Diff line number Diff line change
@@ -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 <id>', 'testcase id')
Expand Down
47 changes: 37 additions & 10 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,42 @@
// tslint:disable-next-line:no-reference
/// <reference path="../typings.d.ts" />
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;
}
Loading