Wait for it…

On my current Rails project, I have been working on constraining “check-ins” to once daily or once weekly. From a Cucumber scenario perspective, this means using Timecop to travel to a specific time/date, popping a jQuery dialog, entering some data, and pressing the Submit button. This procedure is then immediately repeated, traveling to a different point in time. Upon completion of the successful path, I was asserting that both “check-ins” took place by looking at the model/database. Unfortunately, this would fail quite randomly. It was as if the second time travel was taking place before the first check-in was being written to the database. If so, this would cause the second check-in to fail the daily or weekly constraint during validation.

What I needed to do was WAIT — wait for the check-in dialog to close before the second time travel.

It took some poking around, but I finally settled on the following step definition:

When /^I wait for (.*)to finish$/ do |sugar|
  page.wait_until do
    done = page.evaluate_script("window.jQuery.active == 0")
    putc done ? '*' : '+'
    done
  end
end

This allows me to write a step such as:

And I wait for the check-in to finish

This step prints a + every time through the loop while the page is still active, and then a * when it’s done. (Obviously, this is window dressing and not integral to the success of the step.) Not only did this fix the scenario failures I had due to the race condition, it also got rid of the random “connection reset” errors I was seeing.