@qavajs/template
Advanced tools
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.cloneDeep = void 0; | ||
| function cloneDeep(obj) { | ||
| return JSON.parse(JSON.stringify(obj)); | ||
| } | ||
| exports.cloneDeep = cloneDeep; | ||
| //# sourceMappingURL=utils.js.map |
| {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;;AAAA,SAAgB,SAAS,CAAC,GAAQ;IAChC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;AACzC,CAAC;AAFD,8BAEC"} |
| export function cloneDeep(obj: any): any { | ||
| return JSON.parse(JSON.stringify(obj)); | ||
| } |
+6
-1
@@ -0,2 +1,7 @@ | ||
| ## Current | ||
| ## 0.0.4 | ||
| - :rocket: added capability to use templates in other templates | ||
| - :rocket: improved fail stacktrace to include caller template | ||
| ## 0.0.3 | ||
| - fixed issue with templates in scenario outline | ||
| - :beetle: fixed issue with templates in scenario outline |
+71
-27
@@ -35,2 +35,3 @@ "use strict"; | ||
| const cucumber_1 = require("@cucumber/cucumber"); | ||
| const utils_1 = require("./utils"); | ||
| const glob = (0, util_1.promisify)(glob_1.default); | ||
@@ -40,3 +41,15 @@ function findStepDefinition(id, supportCodeLibrary) { | ||
| } | ||
| /** | ||
| * Add template stack trace | ||
| * @param result - original step result | ||
| * @param step - template step invoked failed step | ||
| */ | ||
| function formatErrorMessage(result, step) { | ||
| result.message = `${step.keyword}${step.text}\n${result.message}`; | ||
| return result; | ||
| } | ||
| function parseGherkin(paths) { | ||
| // guard to check if templates found, otherwise gherkin streams hangs | ||
| if (paths.length === 0) | ||
| return Promise.resolve([]); | ||
| return new Promise((resolve, reject) => { | ||
@@ -56,8 +69,12 @@ const messageStream = gherkin_streams_1.GherkinStreams.fromPaths(paths, {}); | ||
| } | ||
| // memo for gherkin documents | ||
| let gherkinDocuments; | ||
| async function loadTemplates() { | ||
| const templatePaths = await global.config.templates.reduce(async (paths, pattern) => (await paths).concat(await glob(pattern)), []); | ||
| const gherkinDocuments = await parseGherkin(templatePaths); | ||
| if (!gherkinDocuments) { | ||
| gherkinDocuments = await parseGherkin(templatePaths); | ||
| } | ||
| const argRegexp = /(<.+?>)/g; | ||
| // memo templates | ||
| const templates = gherkinDocuments | ||
| const templates = (0, utils_1.cloneDeep)(gherkinDocuments) | ||
| .reduce((scenarios, doc) => scenarios.concat(doc.feature ? doc.feature.children : []), []) | ||
@@ -76,3 +93,3 @@ .map((featureChild) => { | ||
| } | ||
| async function runTemplate(templateDefs, compositeStep) { | ||
| async function runTemplate(templateDefs, compositeStep, callerSteps) { | ||
| if (this.isSkippingSteps()) { | ||
@@ -84,2 +101,9 @@ return { | ||
| } | ||
| if (callerSteps.includes(compositeStep)) { | ||
| return { | ||
| status: messages_1.TestStepResultStatus.FAILED, | ||
| message: `${compositeStep} has recursive call`, | ||
| duration: messages_1.TimeConversion.millisecondsToDuration(0), | ||
| }; | ||
| } | ||
| const scenario = templateDefs.find((s) => s.templateRegex.test(compositeStep)); | ||
@@ -92,2 +116,3 @@ if (!scenario) { | ||
| } | ||
| // get scenario arguments | ||
| const matchArgs = compositeStep.match(scenario.templateRegex); | ||
@@ -100,30 +125,40 @@ const args = matchArgs ? matchArgs.splice(1) : []; | ||
| for (const step of scenario.steps) { | ||
| step.text = scenarioArgs.reduce((text, arg) => text.replace(new RegExp(arg.name, 'g'), arg.value), step.text); | ||
| const stepDefinition = stepDefs.stepDefinitions.find((sd) => sd.matchesStepName(step.text)); | ||
| const stepResults = []; | ||
| // try to find template | ||
| if (!stepDefinition) { | ||
| return { | ||
| status: messages_1.TestStepResultStatus.FAILED, | ||
| message: `${step.text} is not defined`, | ||
| duration: messages_1.TimeConversion.millisecondsToDuration(0), | ||
| }; | ||
| const result = await runTemplate.apply(this, [templateDefs, step.text, [...callerSteps, compositeStep]]); | ||
| if (result.status === messages_1.TestStepResultStatus.UNDEFINED) { | ||
| return { | ||
| status: messages_1.TestStepResultStatus.FAILED, | ||
| message: `${step.text} is not defined`, | ||
| duration: messages_1.TimeConversion.millisecondsToDuration(0), | ||
| }; | ||
| } | ||
| stepResults.push(result); | ||
| } | ||
| step.text = scenarioArgs.reduce((text, arg) => text.replace(new RegExp(arg.name, 'g'), arg.value), step.text); | ||
| // run BeforeStep hooks | ||
| let stepResults = await this.runStepHooks(this.getBeforeStepHookDefinitions(), step); | ||
| // run step itself | ||
| let stepResult; | ||
| if ((0, messages_1.getWorstTestStepResult)(stepResults).status !== messages_1.TestStepResultStatus.FAILED) { | ||
| const hookParameter = { | ||
| gherkinDocument: this.gherkinDocument, | ||
| pickle: this.pickle, | ||
| testCaseStartedId: this.currentTestCaseStartedId, | ||
| }; | ||
| stepResult = await this.invokeStep(step, stepDefinition, hookParameter); | ||
| stepResults.push(stepResult); | ||
| else { | ||
| // run BeforeStep hooks | ||
| stepResults.push(...(await this.runStepHooks(this.getBeforeStepHookDefinitions(), step))); | ||
| // run step itself | ||
| let stepResult; | ||
| if ((0, messages_1.getWorstTestStepResult)(stepResults).status !== messages_1.TestStepResultStatus.FAILED) { | ||
| const hookParameter = { | ||
| gherkinDocument: this.gherkinDocument, | ||
| pickle: this.pickle, | ||
| testCaseStartedId: this.currentTestCaseStartedId, | ||
| }; | ||
| stepResult = await this.invokeStep(step, stepDefinition, hookParameter); | ||
| stepResults.push(stepResult); | ||
| } | ||
| // run AfterStep hooks | ||
| const afterStepHookResults = await this.runStepHooks(this.getAfterStepHookDefinitions(), step, stepResult); | ||
| stepResults.push(...afterStepHookResults); | ||
| } | ||
| // run AfterStep hooks | ||
| const afterStepHookResults = await this.runStepHooks(this.getAfterStepHookDefinitions(), step, stepResult); | ||
| stepResults = stepResults.concat(afterStepHookResults); | ||
| // finalizing scenario | ||
| const finalStepResult = (0, messages_1.getWorstTestStepResult)(stepResults); | ||
| if (finalStepResult.status === messages_1.TestStepResultStatus.FAILED) | ||
| return finalStepResult; | ||
| if (finalStepResult.status === messages_1.TestStepResultStatus.FAILED) { | ||
| return formatErrorMessage(finalStepResult, step); | ||
| } | ||
| } | ||
@@ -141,3 +176,12 @@ return { | ||
| if (stepDefinitions.length === 0) { | ||
| return runTemplate.apply(this, [await loadTemplates(), pickleStep.text]); | ||
| // guard to check if templates property provided | ||
| if (!global.config.templates) { | ||
| console.warn('Property templates is not defined. Make sure you have added it to config file'); | ||
| return { | ||
| status: messages_1.TestStepResultStatus.UNDEFINED, | ||
| duration: messages_1.TimeConversion.millisecondsToDuration(0), | ||
| }; | ||
| } | ||
| const templates = await loadTemplates(); | ||
| return runTemplate.apply(this, [templates, pickleStep.text, []]); | ||
| } | ||
@@ -144,0 +188,0 @@ return originRunStep.apply(this, [pickleStep, testStep]); |
+1
-1
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"} |
+1
-1
| { | ||
| "name": "@qavajs/template", | ||
| "version": "0.0.3", | ||
| "version": "0.0.4", | ||
| "description": "library that allow to define step definitions on Gherkin language", | ||
@@ -5,0 +5,0 @@ "scripts": { |
+0
-3
@@ -51,5 +51,2 @@ # @qavajs/template | ||
| default: { | ||
| require: [ | ||
| 'node_modules/@qavajs/steps-config-loader' | ||
| ], | ||
| requireModule: [ | ||
@@ -56,0 +53,0 @@ '@qavajs/template' |
+77
-32
| import * as testCaseRunner from '@cucumber/cucumber/lib/runtime/test_case_runner'; | ||
| import { | ||
| FeatureChild, | ||
| getWorstTestStepResult, | ||
| GherkinDocument, | ||
| PickleStep, | ||
| Scenario, | ||
| TestStep, | ||
| Scenario, Step, | ||
| TestStep, TestStepResult, | ||
| TestStepResultStatus, | ||
| TimeConversion, | ||
| GherkinDocument, | ||
| FeatureChild, | ||
| getWorstTestStepResult, | ||
| } from '@cucumber/messages'; | ||
@@ -17,2 +17,3 @@ import { GherkinStreams } from '@cucumber/gherkin-streams'; | ||
| import { ISupportCodeLibrary } from '@cucumber/cucumber/lib/support_code_library_builder/types'; | ||
| import { cloneDeep } from './utils'; | ||
@@ -35,3 +36,15 @@ declare global { | ||
| /** | ||
| * Add template stack trace | ||
| * @param result - original step result | ||
| * @param step - template step invoked failed step | ||
| */ | ||
| function formatErrorMessage(result: TestStepResult, step: Step): TestStepResult { | ||
| result.message = `${step.keyword}${step.text}\n${result.message}`; | ||
| return result; | ||
| } | ||
| function parseGherkin(paths: Array<string>): Promise<Array<GherkinDocument>> { | ||
| // guard to check if templates found, otherwise gherkin streams hangs | ||
| if (paths.length === 0) return Promise.resolve([]); | ||
| return new Promise((resolve, reject) => { | ||
@@ -52,2 +65,4 @@ const messageStream = GherkinStreams.fromPaths(paths, {}); | ||
| // memo for gherkin documents | ||
| let gherkinDocuments: Array<GherkinDocument>; | ||
| async function loadTemplates() { | ||
@@ -58,6 +73,8 @@ const templatePaths = await global.config.templates.reduce( | ||
| ); | ||
| const gherkinDocuments: Array<GherkinDocument> = await parseGherkin(templatePaths); | ||
| if (!gherkinDocuments) { | ||
| gherkinDocuments = await parseGherkin(templatePaths); | ||
| } | ||
| const argRegexp = /(<.+?>)/g; | ||
| // memo templates | ||
| const templates: Array<ScenarioTemplate> = gherkinDocuments | ||
| const templates: Array<ScenarioTemplate> = cloneDeep(gherkinDocuments) | ||
| .reduce((scenarios: Array<FeatureChild>, doc: GherkinDocument) => scenarios.concat(doc.feature ? doc.feature.children : []), []) | ||
@@ -76,3 +93,3 @@ .map((featureChild: FeatureChild) => { | ||
| async function runTemplate(this: any, templateDefs: Array<ScenarioTemplate>, compositeStep: string) { | ||
| async function runTemplate(this: any, templateDefs: Array<ScenarioTemplate>, compositeStep: string, callerSteps: Array<string>) { | ||
| if (this.isSkippingSteps()) { | ||
@@ -84,2 +101,9 @@ return { | ||
| } | ||
| if (callerSteps.includes(compositeStep)) { | ||
| return { | ||
| status: TestStepResultStatus.FAILED, | ||
| message: `${compositeStep} has recursive call`, | ||
| duration: TimeConversion.millisecondsToDuration(0), | ||
| }; | ||
| } | ||
| const scenario = templateDefs.find((s) => s.templateRegex.test(compositeStep)); | ||
@@ -92,2 +116,3 @@ if (!scenario) { | ||
| } | ||
| // get scenario arguments | ||
| const matchArgs = compositeStep.match(scenario.templateRegex); | ||
@@ -101,29 +126,40 @@ const args = matchArgs ? matchArgs.splice(1) : []; | ||
| for (const step of scenario.steps) { | ||
| step.text = scenarioArgs.reduce((text, arg) => text.replace(new RegExp(arg.name, 'g'), arg.value), step.text); | ||
| const stepDefinition = stepDefs.stepDefinitions.find((sd) => sd.matchesStepName(step.text)); | ||
| const stepResults = []; | ||
| // try to find template | ||
| if (!stepDefinition) { | ||
| return { | ||
| status: TestStepResultStatus.FAILED, | ||
| message: `${step.text} is not defined`, | ||
| duration: TimeConversion.millisecondsToDuration(0), | ||
| }; | ||
| const result = await runTemplate.apply(this, [templateDefs, step.text, [...callerSteps, compositeStep]]); | ||
| if (result.status === TestStepResultStatus.UNDEFINED) { | ||
| return { | ||
| status: TestStepResultStatus.FAILED, | ||
| message: `${step.text} is not defined`, | ||
| duration: TimeConversion.millisecondsToDuration(0), | ||
| }; | ||
| } | ||
| stepResults.push(result); | ||
| } else { | ||
| // run BeforeStep hooks | ||
| stepResults.push(...(await this.runStepHooks(this.getBeforeStepHookDefinitions(), step))); | ||
| // run step itself | ||
| let stepResult; | ||
| if (getWorstTestStepResult(stepResults).status !== TestStepResultStatus.FAILED) { | ||
| const hookParameter = { | ||
| gherkinDocument: this.gherkinDocument, | ||
| pickle: this.pickle, | ||
| testCaseStartedId: this.currentTestCaseStartedId, | ||
| }; | ||
| stepResult = await this.invokeStep(step, stepDefinition, hookParameter); | ||
| stepResults.push(stepResult); | ||
| } | ||
| // run AfterStep hooks | ||
| const afterStepHookResults = await this.runStepHooks(this.getAfterStepHookDefinitions(), step, stepResult); | ||
| stepResults.push(...afterStepHookResults); | ||
| } | ||
| step.text = scenarioArgs.reduce((text, arg) => text.replace(new RegExp(arg.name, 'g'), arg.value), step.text); | ||
| // run BeforeStep hooks | ||
| let stepResults = await this.runStepHooks(this.getBeforeStepHookDefinitions(), step); | ||
| // run step itself | ||
| let stepResult; | ||
| if (getWorstTestStepResult(stepResults).status !== TestStepResultStatus.FAILED) { | ||
| const hookParameter = { | ||
| gherkinDocument: this.gherkinDocument, | ||
| pickle: this.pickle, | ||
| testCaseStartedId: this.currentTestCaseStartedId, | ||
| }; | ||
| stepResult = await this.invokeStep(step, stepDefinition, hookParameter); | ||
| stepResults.push(stepResult); | ||
| // finalizing scenario | ||
| const finalStepResult = getWorstTestStepResult(stepResults); | ||
| if (finalStepResult.status === TestStepResultStatus.FAILED) { | ||
| return formatErrorMessage(finalStepResult, step); | ||
| } | ||
| // run AfterStep hooks | ||
| const afterStepHookResults = await this.runStepHooks(this.getAfterStepHookDefinitions(), step, stepResult); | ||
| stepResults = stepResults.concat(afterStepHookResults); | ||
| const finalStepResult = getWorstTestStepResult(stepResults); | ||
| if (finalStepResult.status === TestStepResultStatus.FAILED) return finalStepResult; | ||
| } | ||
@@ -142,5 +178,14 @@ return { | ||
| if (stepDefinitions.length === 0) { | ||
| return runTemplate.apply(this, [await loadTemplates(), pickleStep.text]); | ||
| // guard to check if templates property provided | ||
| if (!global.config.templates) { | ||
| console.warn('Property templates is not defined. Make sure you have added it to config file'); | ||
| return { | ||
| status: TestStepResultStatus.UNDEFINED, | ||
| duration: TimeConversion.millisecondsToDuration(0), | ||
| }; | ||
| } | ||
| const templates = await loadTemplates(); | ||
| return runTemplate.apply(this, [templates, pickleStep.text, []]); | ||
| } | ||
| return originRunStep.apply(this, [pickleStep, testStep]); | ||
| }; |
30092
20.93%17
21.43%422
29.85%59
-4.84%