Read more

Nested Spreewald patiently blocks are now patient

Henning Koch
February 09, 2018Software engineer at makandra GmbH

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

Illustration UI/UX Design

UI/UX Design by makandra brand

We make sure that your target audience has the best possible experience with your digital product. You get:

  • Design tailored to your audience
  • Proven processes customized to your needs
  • An expert team of experienced designers
Read more Show archive.org snapshot

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.

Posted by Henning Koch to makandra dev (2018-02-09 12:33)