cucumber-js
cucumber-js copied to clipboard
Consumer-centric facade for the running test case
Is your feature request related to a problem? Please describe.
The Before hook is passed a testCase object (ITestCaseHookParameter type) that's not really designed with the user in mind.
For example, a user had to do this in order to access the cells from the examples table that the running scenario came from:
Before((testCase: ITestCaseHookParameter) => {
const examplesMap = new Map()
const scenarioId = testCase.pickle.astNodeIds[0]
const exampleId = testCase.pickle.astNodeIds[1]
const scenario = testCase.gherkinDocument.feature.children.find((child) => child.scenario.id === scenarioId)
const cells = scenario.scenario.examples[0].tableHeader.cells
const values = scenario.scenario.examples[0].tableBody.find((body) => body.id === exampleId)
cells.forEach((cell, index) => {
examplesSet.set(cell.value, values.cells[index].value)
})
console.log(examplesMap)
})
Describe the solution you'd like
I suggest we wrap this testCase object with an API designed from the user's conceptual model of a running scenario - so containing any information we have about the current test status, but also containing easy access to the Gherkin source of the test case too. We do something like this in Ruby.
For example:
Before((scenario: RunningScenario) => {
console.log(scenario.exampleRow?.cells)
})
or
Before((scenario: RunningScenario) => {
console.log(scenario.feature.name)
})
but also
Before((scenario: RunningScenario) => {
console.log(scenario.result)
})
or
Before((scenario: RunningScenario) => {
console.log(scenario.steps[0].result)
})
Additional context
An additional benefit of this layer of indirection is that we insulate our underlying types from dependencies from user-land code, leaving us more free to change these internal types if we need to. Right now, we're exposing types from the messages project right out to users, so if we want to change those messages we have large ripple effects.
We had that kind of discussion with cucumber-ruby That led to that comment from you: https://github.com/cucumber/cucumber-ruby/issues/1432#issuecomment-885153793
@brasmusson really clarified it for me today at the Zoom community meeting, that the hooks are part of an execution model, and we should keep the info exposed in them lean because, for example, we might have test cases that were generated from sources other than Gherkin documents, or test cases running in parallel.
On the other hand, the events API used by the formatters is the higher-level place where you can observe everything going on in the Cucumber run, including AST nodes and execution results.
I think we're probably missing an abstraction layer that makes it easier to work with the events API for common use cases, so please keep talking to us and see if there are patterns in what you do with it that could be pushed upstream.
Noting some overlap with https://github.com/cucumber/html-formatter/issues/283, where we also want a coherent way to express a test case for the purposes of the HTML formatter components.