///|
/// Execute a single scenario from a compiled Pickle.
pub fn execute_scenario(
registry : @core.StepRegistry,
feature_name~ : String,
scenario_name~ : String,
pickle_id~ : String,
tags~ : Array[String],
steps~ : Array[@cucumber_messages.PickleStep],
) -> ScenarioResult {
let step_results : Array[StepResult] = []
let mut failed = false
for step in steps {
let keyword = match step.type_ {
Some(@cucumber_messages.PickleStepType::Context) => "Given "
Some(@cucumber_messages.PickleStepType::Action) => "When "
Some(@cucumber_messages.PickleStepType::Outcome) => "Then "
_ => "* "
}
if failed {
step_results.push({
text: step.text,
keyword,
status: StepStatus::Skipped,
duration_ms: 0L,
})
continue
}
let status = match registry.find_match(step.text) {
None => StepStatus::Undefined
Some((handler, args, _)) =>
try {
(handler.0)(args)
StepStatus::Passed
} catch {
e => StepStatus::Failed(e.to_string())
}
}
match status {
StepStatus::Failed(_) | StepStatus::Undefined => failed = true
_ => ()
}
step_results.push({ text: step.text, keyword, status, duration_ms: 0L })
}
let statuses = step_results.map(fn(r) { r.status })
{
feature_name,
scenario_name,
pickle_id,
tags,
steps: step_results,
status: ScenarioStatus::from_steps(statuses),
duration_ms: 0L,
}
}
///|
/// Execute a single scenario with lifecycle hooks.
/// Calls before/after_scenario and before/after_step on the world.
pub fn[W : @core.Hooks] execute_scenario_with_hooks(
world : W,
registry : @core.StepRegistry,
feature_name~ : String,
scenario_name~ : String,
pickle_id~ : String,
tags~ : Array[String],
steps~ : Array[@cucumber_messages.PickleStep],
) -> ScenarioResult {
let info : @core.ScenarioInfo = { feature_name, scenario_name, tags }
// before_scenario hook
let hook_err = try {
@core.Hooks::before_scenario(world, info)
None
} catch {
e => Some(e.to_string())
}
if hook_err is Some(msg) {
// All steps skipped when before_scenario fails
let step_results = steps.map(fn(step) {
let keyword = match step.type_ {
Some(@cucumber_messages.PickleStepType::Context) => "Given "
Some(@cucumber_messages.PickleStepType::Action) => "When "
Some(@cucumber_messages.PickleStepType::Outcome) => "Then "
_ => "* "
}
{ text: step.text, keyword, status: StepStatus::Skipped, duration_ms: 0L }
})
let _ = @core.Hooks::after_scenario(world, info, Some(msg)) catch {
_ => ()
}
return {
feature_name,
scenario_name,
pickle_id,
tags,
steps: step_results,
status: ScenarioStatus::Failed,
duration_ms: 0L,
}
}
// Execute steps with before/after_step hooks
let step_results : Array[StepResult] = []
let mut failed = false
let mut scenario_error : String? = None
for step in steps {
let keyword = match step.type_ {
Some(@cucumber_messages.PickleStepType::Context) => "Given "
Some(@cucumber_messages.PickleStepType::Action) => "When "
Some(@cucumber_messages.PickleStepType::Outcome) => "Then "
_ => "* "
}
if failed {
step_results.push({
text: step.text,
keyword,
status: StepStatus::Skipped,
duration_ms: 0L,
})
continue
}
let step_info : @core.StepInfo = { keyword, text: step.text }
// before_step hook
let before_err = try {
@core.Hooks::before_step(world, step_info)
None
} catch {
e => Some(e.to_string())
}
let status = if before_err is Some(msg) {
StepStatus::Failed(msg)
} else {
match registry.find_match(step.text) {
None => StepStatus::Undefined
Some((handler, args, _)) =>
try {
(handler.0)(args)
StepStatus::Passed
} catch {
e => StepStatus::Failed(e.to_string())
}
}
}
// after_step hook
let step_result_msg : String? = match status {
StepStatus::Failed(msg) => Some(msg)
_ => None
}
let _ = @core.Hooks::after_step(world, step_info, step_result_msg) catch {
_ => ()
}
match status {
StepStatus::Failed(msg) => {
failed = true
scenario_error = Some(msg)
}
StepStatus::Undefined => {
failed = true
scenario_error = None
}
_ => ()
}
step_results.push({ text: step.text, keyword, status, duration_ms: 0L })
}
// after_scenario hook
let _ = @core.Hooks::after_scenario(world, info, scenario_error) catch {
_ => ()
}
let statuses = step_results.map(fn(r) { r.status })
{
feature_name,
scenario_name,
pickle_id,
tags,
steps: step_results,
status: ScenarioStatus::from_steps(statuses),
duration_ms: 0L,
}
}