@amiceli/vitest-cucumber
Version:
vitest tools to use Gherkin feature in unit tests
88 lines (87 loc) • 3.86 kB
JavaScript
import { afterAll, beforeAll, onTestFailed, test } from 'vitest';
import { getVitestCucumberConfiguration } from '../configuration';
import { defineStepToTest, orderStepsToRun } from './define-step-test';
export function createScenarioOutlineDescribeHandler({ scenario, predefinedSteps, mappedExamples, scenarioTestCallback, afterEachScenarioHook, beforeEachScenarioHook, }) {
let scenarioStepsToRun = [];
const config = getVitestCucumberConfiguration();
function addPredefinedSteps(list) {
const missingSteps = scenario.steps.filter((step) => {
return (scenarioStepsToRun.find((s) => {
return step.matchStep(s.step);
}) === undefined);
});
for (const predefineStep of list) {
const missingStep = missingSteps.find((s) => {
return s.matchStep(predefineStep.step);
});
if (missingStep) {
scenarioStepsToRun.push(defineStepToTest({
parent: scenario,
stepDetails: predefineStep.step.details,
stepType: predefineStep.step.type,
scenarioStepCallback: predefineStep.fn,
}));
}
}
scenarioStepsToRun = orderStepsToRun(scenario, scenarioStepsToRun);
}
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: {},
};
const example = scenario.examples;
if (example) {
return example?.map((exampleVariables) => {
const mappedExampleVariables = Object.fromEntries(Object.entries(exampleVariables).map(([index, value]) => {
return [index, mappedExamples[value] ?? value];
}));
scenarioStepsToRun = [];
scenarioTestCallback(scenarioStepsCallback, mappedExampleVariables);
addPredefinedSteps(predefinedSteps);
scenario.checkIfStepWasCalled();
return ((steps) => function scenarioOutlineDescribe() {
beforeAll(async () => {
await beforeEachScenarioHook();
});
afterAll(async () => {
await afterEachScenarioHook();
});
test.for(steps.map((s) => {
return [
scenario.getStepTitle(s.step, exampleVariables),
s,
];
}))(`%s`, async ([, scenarioStep], ctx) => {
if (scenarioStep.step.docStrings) {
scenarioStep.params[scenarioStep.params.length - 1] = scenario.getStepDocStrings(scenarioStep.step, mappedExampleVariables);
}
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);
});
})([...scenarioStepsToRun]);
});
}
return [];
}