🤔 What's the problem you're trying to solve?
Currently, a Gherkin step can have either a DocString or a DataTable, but not both.
This is limiting for cases where the two argument types represent different parts of the same action or assertion. For example, a DocString can naturally represent a request body, GraphQL query, SQL statement, template, or expected text, while a DataTable can represent structured parameters, metadata, expected rows, or assertions for that same step.
The current mutual exclusivity means downstream runners and libraries cannot model such steps directly, even though the AST/message model already has separate docString and dataTable fields.
I want to discuss whether this exclusivity is intentional and should remain, or whether Gherkin should allow one DocString and one DataTable on the same step.
✨ What's your proposed solution?
Allow a single step to contain both existing argument kinds:
- zero or one DocString
- zero or one DataTable
This is not a proposal for arbitrary multiple step arguments. It should not allow repeated DocStrings, repeated DataTables, or a general ordered stepArguments[] collection.
Example:
Given I send a request
"""
{ "name": "Bob" }
"""
| status | message |
| 201 | created |
⛏ Have you considered any alternatives or workarounds?
One workaround is to split the step into multiple steps. That works, but it can make a single logical action harder to read when the DocString and DataTable are both part of the same operation.
Another workaround is to encode the structured data inside the DocString, for example as JSON or YAML. That loses the readability and ergonomics of DataTables.
A third workaround is to encode the text payload inside a DataTable cell. That is usually worse for larger text blocks, request bodies, SQL, GraphQL, XML, Markdown, etc.
I do not think supporting multiple DocStrings or multiple DataTables is a good alternative. That would be a much broader feature requiring a real collection model, ordering rules, formatter behavior, runner API changes, and probably additional syntax to distinguish repeated arguments. The proposal here is intentionally narrower.
📚 Any additional context?
This came up from a PR that attempted to allow both a DocString and a DataTable on the same step. Feedback on that PR raised valid concerns about ordering, pretty formatting, runner APIs, and broader ecosystem impact.
I would like to use this issue to gather consensus before treating the behavior as settled.
In particular, feedback would be useful from maintainers and consumers of Cucumber-JS, Cucumber-JVM, Cucumber-Ruby, Reqnroll, godog, and other projects using the Gherkin parser.
Questions to discuss:
- Should
docString and dataTable remain mutually exclusive?
- If both are allowed, should both syntactic orders be valid?
- Should there be one canonical order only?
- Should runners expose these by type/name rather than as positional arguments?
- Would this create practical compatibility issues for existing formatters or runner APIs?
🤔 What's the problem you're trying to solve?
Currently, a Gherkin step can have either a DocString or a DataTable, but not both.
This is limiting for cases where the two argument types represent different parts of the same action or assertion. For example, a DocString can naturally represent a request body, GraphQL query, SQL statement, template, or expected text, while a DataTable can represent structured parameters, metadata, expected rows, or assertions for that same step.
The current mutual exclusivity means downstream runners and libraries cannot model such steps directly, even though the AST/message model already has separate
docStringanddataTablefields.I want to discuss whether this exclusivity is intentional and should remain, or whether Gherkin should allow one DocString and one DataTable on the same step.
✨ What's your proposed solution?
Allow a single step to contain both existing argument kinds:
This is not a proposal for arbitrary multiple step arguments. It should not allow repeated DocStrings, repeated DataTables, or a general ordered
stepArguments[]collection.Example:
⛏ Have you considered any alternatives or workarounds?
One workaround is to split the step into multiple steps. That works, but it can make a single logical action harder to read when the DocString and DataTable are both part of the same operation.
Another workaround is to encode the structured data inside the DocString, for example as JSON or YAML. That loses the readability and ergonomics of DataTables.
A third workaround is to encode the text payload inside a DataTable cell. That is usually worse for larger text blocks, request bodies, SQL, GraphQL, XML, Markdown, etc.
I do not think supporting multiple DocStrings or multiple DataTables is a good alternative. That would be a much broader feature requiring a real collection model, ordering rules, formatter behavior, runner API changes, and probably additional syntax to distinguish repeated arguments. The proposal here is intentionally narrower.
📚 Any additional context?
This came up from a PR that attempted to allow both a DocString and a DataTable on the same step. Feedback on that PR raised valid concerns about ordering, pretty formatting, runner APIs, and broader ecosystem impact.
I would like to use this issue to gather consensus before treating the behavior as settled.
In particular, feedback would be useful from maintainers and consumers of Cucumber-JS, Cucumber-JVM, Cucumber-Ruby, Reqnroll, godog, and other projects using the Gherkin parser.
Questions to discuss:
docStringanddataTableremain mutually exclusive?