Running BDD

Features run through one of two paths, both driven by the same TestRunner.

ferridriver bdd (the CLI)

Primary path. Runs Gherkin features through the core test runner with Rust and / or JS / TS step bodies — no Node, no Bun:

# Rust steps only
ferridriver bdd tests/features/

# With JavaScript / TypeScript step files
ferridriver bdd \
  --steps 'steps/**/*.{js,ts}' \
  --tags '@smoke and not @wip' \
  --workers 4 \
  --reporter junit \
  --reporter terminal \
  tests/features/

--steps is repeatable and overrides [test].steps from the config file. Defaults to steps/**/*.{js,ts} and step_definitions/**/*.{js,ts} when omitted.

Flags

--steps GLOB              JS / TS step files (repeatable)
--tags EXPR               tag filter: @smoke and not @wip, etc.
--workers N               parallel workers (default: CPU count)
--reporter NAME           reporter name (repeatable)
--strict                  treat undefined / pending steps as failures (default)
--no-strict               report undefined / pending steps without failing
--dry-run                 parse + report scenarios without executing
--fail-fast               stop after first failure
--step-timeout MS         override per-step timeout
--order MODE              defined | random | random:SEED
--language LANG           default Gherkin keyword language (en, de, fr, ...)
--shard X/N               run shard X of N across CI machines
--world-parameters JSON   pass JSON object to this.parameters

Plus the shared browser flags (--backend, --headless, --executable-path, --connect, --auto-connect, --user-data-dir).

Rust / cargo test

Use bdd_main!() as the binary entry point and the shared runner flags:

// tests/bdd.rs
ferridriver_bdd::bdd_main!();
# Cargo.toml
[[test]]
name = "bdd"
path = "tests/bdd.rs"
harness = false

[dev-dependencies]
ferridriver-bdd  = "0.4"
ferridriver-test = "0.4"
cargo test --test bdd -- -j 4 --tags '@smoke and not @wip'

Tests run headed by default; pass --headless to opt into headless mode.

Reporters

ReporterOutput
terminalGherkin-formatted hierarchy with colors (default)
progressCompact dot-based status
dotOne character per scenario
jsonMachine-readable JSON
junitJUnit XML (CI-friendly)
htmlSelf-contained HTML report
cucumber-jsonCucumber JSON format (dashboards)
messages / ndjsonCucumber Messages NDJSON stream
usageStep expression call counts + duration
rerunFailed scenario file:line for re-execution
githubGitHub Actions annotations
emptyNo output

Specify multiple reporters by repeating --reporter, e.g. --reporter terminal --reporter junit. Each name is matched exactly (no name:path syntax). File-writing reporters emit into the run's output directory — junit writes junit.xml, json writes results.json. Set the path or per-reporter options with a [[test.reporter]] table in the config file. A name that is neither built in nor a path to a reporter module is refused with the list above; see custom reporters.

The cucumber-json document

cucumber-json writes the document cucumber's own ecosystem reads, field for field: a feature's id, line, description and tags[] (each with the line it was written on), an element's id (feature;rule;scenario), keyword, line and description, and a step's line, arguments (a data table as {rows:[{cells}]}, a doc string as {content, line}) and result.duration in nanoseconds. Hooks appear as hidden steps keyworded Before or After.

Feature entries are keyed on the file AND the project, so a run over several projects produces one entry per project rather than merging them; the entry's id carries the project name.

OptionDefaultEffect
skipAttachmentstrueAttachment bodies are large; set false to emit them as base64 embeddings
addProjectToFeatureNamefalsePut the project in the feature's name, not only its id
addMetadataunset"object" or "list" — add {Project, Browser} to each feature

There is no cucumber-html reporter. The HTML report is produced from this document by the tool that owns the format (cucumber-html-reporter, multiple-cucumber-html-reporter), which reads exactly the file cucumber-json writes.

Environment variables

The shared runner env vars apply (see CLI reference — FERRIDRIVER_DEBUG, FERRIDRIVER_PROFILE, RUST_LOG, etc.).