UNPKG

@amiceli/vitest-cucumber

Version:

vitest tools to use Gherkin feature in unit tests

90 lines (89 loc) 3.57 kB
import { afterAll, beforeAll, onTestFailed, test } from 'vitest'; import { ExpressionStep } from '../../parser/expression/ExpressionStep'; import { getVitestCucumberConfiguration } from '../configuration'; import { defineStepToTest, orderStepsToRun } from './define-step-test'; export function createScenarioDescribeHandler({ scenario, predefinedSteps, scenarioTestCallback, afterEachScenarioHook, beforeEachScenarioHook, }) { let scenarioStepsToRun = []; const config = getVitestCucumberConfiguration(); const createScenarioStepCallback = (stepType) => { return (stepDetails, scenarioStepCallback) => { scenarioStepsToRun.push(defineStepToTest({ parent: scenario, stepDetails, stepType, scenarioStepCallback, })); }; }; const scenarioStepsCallback = { Given: createScenarioStepCallback(`Given`), When: createScenarioStepCallback(`When`), And: createScenarioStepCallback(`And`), Then: createScenarioStepCallback(`Then`), But: createScenarioStepCallback(`But`), context: {}, }; scenarioTestCallback(scenarioStepsCallback); const missingSteps = scenario.steps.filter((step) => { return (scenarioStepsToRun.find((s) => { return step.matchStep(s.step); }) === undefined); }); for (const predefineStep of predefinedSteps) { const matchingSteps = missingSteps.filter((featureStep) => { if (featureStep.type !== predefineStep.step.type) { return false; } if (featureStep.details === predefineStep.step.details) { return true; } if (predefineStep.compiledPattern) { predefineStep.compiledPattern.regex.lastIndex = 0; return predefineStep.compiledPattern.regex.test(featureStep.details); } return false; }); for (const missingStep of matchingSteps) { const params = ExpressionStep.matchStep(missingStep, predefineStep.step.details); scenarioStepsToRun.push({ key: missingStep.getTitle(), fn: predefineStep.fn, step: missingStep, params: [ ...params, missingStep.dataTables.length > 0 ? missingStep.dataTables : null, missingStep.docStrings, ].filter((p) => p !== null), }); missingStep.isCalled = true; } } scenarioStepsToRun = orderStepsToRun(scenario, scenarioStepsToRun); scenario.checkIfStepWasCalled(); return function scenarioDescribe() { beforeAll(async () => { await beforeEachScenarioHook(); }); afterAll(async () => { await afterEachScenarioHook(); }); test.for(scenarioStepsToRun.map((s) => { return [ s.key, s, ]; }))(`%s`, async ([, scenarioStep], ctx) => { onTestFailed(({ task }) => { const message = task.result?.errors?.at(0)?.message; config.onStepError({ error: new Error(message || `${scenarioStep.step.details} failed`), ctx, step: scenarioStep.step, }); }); await scenarioStep.fn(ctx, ...scenarioStep.params); }); }; }