Open Odonno opened 5 days ago
Thanks for all your great proposals. With regards to this one, an addition that would be great is to add a config option for a code fragment that pulls in custom setup code. I have a support file and some basic assignments that are at the top of each of my tests. It would be great to define all that in a file to include and to add that code fragment via the config filepath when generating a new test file. eg:
// All my custom setup code
import { graphDB, msRequest, msBroadcast, msReceive, loadFeature, describeFeature, setupServerForTests, checkValidReceivedMessage, isISO8601, toBoolean } from 'test/vitest/__tests__/helpers/startupTestBusinessLogicClasses.js'
const loopServerIn = inject('loopServerIn')
import { basetestdata } from 'test/vitest/__tests__/testData/baseData.js'
let forceLoopServerIn
const useServerForTest = (forceLoopServerIn !== null) ? forceLoopServerIn : loopServerIn
Thanks again for continuing the development of this great library. Murray
Vite plugin is really a good idea but I will see that in another project like vite-cucumber-plugin
.
It will use vitest-cucumber
for CLI etc but all code to detect file changes and update tests/shared according changes, generate new tests etc, in another project.
I never code a vite plugin but I can check how it works, docs, examples etc and maybe scratch an alpha
project.
The proposition is to go beyond the current provided CLI and to offer a built-in Vite plugin to generate the js/ts file architecture from feature files, relatively similar to the TanStack Router vite plugin.
Implementation details
The idea is to provide a fairly straightforward solution that automatically generate feature/scenario/step definitions files and the underlying folder architecture. But file generation is only the starting point as the ideal solution would be to keep the architecture completely in sync on every feature file change:
Having a predictable file architecture would allow such complex workflow letting the developer purely focus on the changes to make in each step definition (and possibly in-between scenarii and steps).
Setup & configuration
A minimal vite config could look like this:
The previous example will use the default configuration. A fully configurated vite config using the
CucumberVite
plugin could look like this:Modes
The goal is to craft the ideal solution which would be the full autopilot/full sync mode. However, it can be 1. easier to build in steps and it can be 2. interesting to offer a way to provide a progressive enhancement from nothing to the full syncing mode, for cases when integrating this plugin into a brownfield project is impossible or when the full-sync mode feels too "aggressive".
A set of 3 modes can be integrated and built upon in the solution. From simplest to more feature complete:
feature
level, only generate new scenario on file changescenario
level, like 1. but it can also generate new steps in a scenario definition when new steps are added on file changefull sync
, the one depicted earlier which offers the best experience possible and syncing on every changeQuestion: quid of the renaming and the removal of file/scenario/step on
feature
andscenario
levels?new feature
Let's take the following Gherkin definition from an hypothetic feature file:
This can generate a new definition file like this:
refactoring
The refactoring is applied when and only when the same step is used at least twice, both the step text and the step definition code. This refactoring can happen whether a feature file reuse the same step across 2+ scenarii or whether a step already exist in a scenario of another feature file.
Let's start with a feature file that will trigger a refactoring:
This will generate both the definition file and the shared step definition file.
Note: the generated "shared step" will be named
givenDeveloperUsingFeatureFile.ts
Note 2: we can imagine that the shared step naming convention can be configured globally via the configuration (either via defined presets
"camelCase" | "pascalCase" | "kebabCase" | "snakeCase"
and/or simply via a function(stepName: string) => string
)The decision of having a single step per file is based on previous experiences where having N+ shared steps in a single step would re-trigger more tests than expected on a single step change because the test runner is incapable to detect which step has been changed and so which import is triggering a change.
Again, by enabling the autopilot mode, this opinionated decision is a no-brainer as the "shared step" file will be created/removed automatically by the Vite cucumber plugin.