@amiceli/vitest-cucumber
Version:
vitest tools to use Gherkin feature in unit tests
81 lines (80 loc) • 3.2 kB
JavaScript
import { onTestFailed, test } from 'vitest';
import { ExpressionStep } from '../../parser/expression/ExpressionStep';
import { getVitestCucumberConfiguration } from '../configuration';
import { defineStepToTest, orderStepsToRun } from './define-step-test';
export function createBackgroundDescribeHandler({ background, predefinedSteps, backgroundCallback, }) {
let backgroundStepsToRun = [];
const config = getVitestCucumberConfiguration();
const createScenarioStepCallback = (stepType) => {
return (stepDetails, scenarioStepCallback) => {
backgroundStepsToRun.push(defineStepToTest({
parent: background,
stepDetails,
stepType,
scenarioStepCallback,
}));
};
};
const scenarioStepsCallback = {
Given: createScenarioStepCallback(`Given`),
And: createScenarioStepCallback(`And`),
context: {},
};
backgroundCallback(scenarioStepsCallback);
const missingSteps = background.steps.filter((step) => {
return (backgroundStepsToRun.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);
backgroundStepsToRun.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;
}
}
backgroundStepsToRun = orderStepsToRun(background, backgroundStepsToRun);
background.checkIfStepWasCalled();
return function backgroundDescribe() {
test.for(backgroundStepsToRun.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);
});
};
}