Synchronization and Waiting ⌚️

In order to prevent race conditions and avoid flaky tests, it's important that any expectations that depend on asynchronous outcomes are retried.

Most capybara methods will automatically retry until they succeed or a certain timeout ellapses.

All finders, assertions, matchers, and some actions allow passing a :wait keyword to specify how many seconds the command should be retried before failing or returning control.

Manual Synchronization ⏱

Automatic synchronization does not apply if you are writing your own expectations.

You can make any expectation retry automatically until timeout by wrapping it with synchronize_expectation:

  def be_fullscreen
    synchronize_expectation {
      expect(fullscreen?).to_or not_to, eq(true)
    }
  end

Automatic Reload ♻️

Elements will be automatically reloaded by Capybara as the block is retried, so it works nicely with any element methods.

def be_checked
  synchronize_expectation(wait: 3) { expect(checked?).to_or not_to, eq(true) }
end

TIP

Using strict settings will prevent flaky tests and save you time in the long run.

Capybara.configure do |config|
  config.default_max_wait_time = 2
  config.exact = true
  config.match = :smart
  config.ignore_hidden_elements = true
end