Skip to main content

Module bdd

Module bdd 

Source
Expand description

Cucumber step-definition surface for the shared QuickJS engine.

The same VM that runs ferridriver run scripts and MCP run_script also loads cucumber-js-shaped .js step files. Given/When/ Then/Before/After/defineParameterType/… are native Rust functions (no JS glue); registrations land in a Rust ExtensionRegistry held as context userdata (the QuickJS context is single-threaded, so a RefCell is the right interior mutability — no Arc/Mutex). Step bodies are kept as Persistent functions and called back by the Rust ferridriver-bdd core. Every body receives the per-scenario World as its FIRST positional argument — arrow, classic function, async, all the same shape — followed by the cucumber-extracted parameters, an optional DataTableJs, and an optional doc-string. The World is also bound as this so function (world) { this === world } holds for callers who prefer that style.

No business logic here: matching, outline expansion, tag filtering and hook ordering all stay in the ferridriver-bdd core.

Structs§

CollectedAllow
Capability allow-list snapshot. Serialises to the exact JSON the MCP PluginAllow deserialises (commands + net, camelCase) so the loader needs no JS round-trip to recover manifests.
CollectedHook
CollectedParamType
CollectedRegistry
CollectedStep
Step metadata read back by the ferridriver-bdd core to build its Cucumber-Expression registry. Straight off the Rust registry — no JS round-trip.
CollectedTool
One registered tool’s manifest, read straight off the Rust registry. Field layout + camelCase match MCP PluginManifest so a serde_json round-trip reconstructs it without re-running the plugin.
DataTableJs
A cucumber data table, passed to steps as the trailing argument.
HookArg
The argument cucumber-js passes to Before/After hooks. Built by the BDD layer and lowered to a JS object { pickle: { name, tags }, result: { status, message? } } in invoke_hook — enough for the screenshot-on-failure idiom (After(s => { if (s.result.status === 'FAILED') this.attach(...) })).
ScenarioWorld
Per-scenario fixtures the BDD core threads onto the JS World — the same handles RunContext carries for scripting, installed onto a per-scenario World object rather than globalThis.
ScriptAttachment
One Cucumber attachment produced by this.attach(...) / this.log(...) during a scenario. Drained by the BDD layer into the test result so the messages / HTML / Allure reporters surface it (screenshot- and text-on-failure).

Enums§

JsArg
A cucumber-extracted step argument, lowered directly to a JS value (never through serde_json — a transitive dep may enable serde_json/arbitrary_precision, which would turn numbers into objects).
StepKind
Cucumber step keyword. Step is keyword-agnostic (defineStep, And, But); matching in the core is keyword-agnostic anyway.
StepOutcome
Outcome of a JS step/hook beyond plain pass (cucumber return protocol: returning the string 'pending'/'skipped').

Functions§

collect_registry
Snapshot the registry after the step .js files evaluated.
drain_attachments
Drain the scenario’s queued attachments (and clear the queue). The BDD layer calls this after each scenario and forwards them into the test result so the reporters surface them.
install_bdd
Install the native cucumber + MCP-tool surface and the shared extension registry as context userdata. Idempotent; called once at Session::create.
invoke_hook
Invoke hook idx. Same bridge as invoke_step.
invoke_step
Invoke step idx with cucumber-extracted args, the optional data table and doc string, against the current World. A thrown JS error becomes a ScriptError carrying the .js location.
reset_world
Drop the per-scenario World (cucumber builds a fresh one per scenario). The next set_scenario_world installs a new one.
set_scenario_world
Build the per-scenario World and make it the this steps run against. If setWorldConstructor was used, that class is constructed and the fixtures are augmented onto the instance.
tool_names
The ordered tool names — drives building the native plugins.<name> surface.
tools_len
Number of tools registered so far — lets the loader slice each bundled file’s contributions out of the shared registry.
tools_snapshot
Snapshot every registered tool manifest, in registration order. Synchronous (&Ctx) so the bundle/extraction path can call it inside its own async_with! without a second context hop.