Question

When using capybara-webkit or poltergeist to test JavaScript behavior, I often find (or unfortunately, write) tests that look like this

it "saves the check box value when clicked", js: true do
  visit '/somewhere'

  page.should have_unchecked_field 'cool_check_box'

  page.check 'cool_check_box'

  visit '/somewhere'

  page.should have_checked_field 'cool_check_box'
end

... where checking the checkbox makes some AJAX request that saves whatever state allows it to be checked after a quick reload.

That test seems guaranteed to flake, because if the AJAX request doesn't complete by the time the second visit '/somewhere' happens, it will load with the checkbox in the wrong state.

Luckily on this page there's also a spinner that spins along while the checkbox request is completing, so I can amend the test like so

it "saves the check box value when clicked", js: true do
  visit '/somewhere'

  page.should have_unchecked_field 'cool_check_box'

  page.check 'cool_check_box'

  # Wait for checkbox ajax to complete
  page.should have_css('.spinner:not(.active)')

  visit '/somewhere'

  page.should have_checked_field 'cool_check_box'
end

I'm still a little paranoid, though: if the page.check line ran but didn't manage to set the spinner as active before the page.should have_css line, that line would succeed before the request even started.

Given that the JavaScript triggered by the checkbox sets the active class, can I guarantee this test will never flake?

Was it helpful?

Solution

What you're talking about is the risk of the code that handles the check event running concurrently to the code which checks for .spinner:not(.active). This is not a risk since the Javascript on the page is single-threaded - you can guarantee that the check even will be handled first.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top