Nested Spreewald patiently blocks are now patient

Updated . Posted . Visible to the public.

In Spreewald 1.10.4+, nested patiently blocks are now patient.

Here is an example:

patiently do
  outer_code
  patiently do
    inner_code
  end
end

On spreewald 1.11.2+ the inner block will wait for the full configured wait time (by default 5 seconds). The outer patiently block would now be out of time, but it will always be retried at least a second time. This behavior allows with_scope to be patient, and it must be patient, as explained below.

In versions 1.10.4 - 1.11.1, inner blocks would keep giving the outer block additional time to finish, which solves the same issues, but as a downside can cause the whole step to take extremely long if it was actually supposed to fail.

In even earlier versions of Spreewald the outer patiently would wait for 5 seconds and all inner patientlys would not wait at all.

with_scope must be patient

Since 90% of the time you will have nested patiently block is when using with_scope (Cucumber: ... within ...), here is some information about this issue:

Using with_scope without patiently will sometimes break:

with_scope('.container') do  # => this caches the container element
                             # => here JavaScript swaps the container element
  page.find('.child')        # => tries to find a child of the previously cached container
                             # => Selenium explodes because the container is detached from the DOM
end

Unfortunately we cannot fix this by making sure that the element exists before we enter with_scope:

patiently do
  expect(page).to have_css('.container') # => asserts that a container element is on the page
end

with_scope('.container') do  # => this caches the container element
                             # => here JavaScript swaps the container element
  page.find('.child')        # => tries to find a child of the previously cached container
                             # => Selenium explodes because the container is detached from the DOM
end

The only way to make this work is wrap it in patiently:

patiently do
  with_scope('.container') do
    page.find('.child')
  end  
end

This used to be an issue with how nested patiently blocks worked in the past.

In Spreewald 1.10.4+ the ... within ... step is patient again.

Henning Koch
Last edit
Henning Koch
License
Source code in this card is licensed under the MIT License.
Posted by Henning Koch to makandra dev (2018-02-09 11:33)