Skip to content

Allowing both DocString and DataTable on a single step #593

@kruczekrobert

Description

@kruczekrobert

🤔 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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions