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

Posted . Visible to the public.

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
Profile picture of Henning Koch
Henning Koch
Last edit
Michael Leimstädtner
License
Source code in this card is licensed under the MIT License.
Posted by Henning Koch to makandra dev (2023-01-23 21:19)