Spreewald: patiently blocks must not change variables from the surrounding scope

I recently enjoyed debugging a Cucumber step that tried to be retryable using a patiently Show archive.org snapshot block:

Then /^"([^"]*)" should( not)? be selected for "([^"]*)"$/ do |value, negate, field|
  patiently do
    field = find(:label, text: field)['for'].delete_suffix('-ts-control')
    ...
  end
end

Unfortunately this block is not retryable:

  • The first attempt changes the value of field.
  • All subsequent attempts will using the changed value of field, instead of the original step arguments.

All variables declared within a patiently block must be scoped to that block. The example above needs to be changed to something like this:

Then /^"([^"]*)" should( not)? be selected for "([^"]*)"$/ do |value, negate, label|
  patiently do
    # Note that the "field" value is now local and not shared between patiently retries
    field = find(:label, text: label)['for'].delete_suffix('-ts-control')
    ...
  end
end
Henning Koch Over 1 year ago