Method: Capybara::Node::Base#synchronize

Defined in:
lib/capybara/node/base.rb

- (Object) synchronize(seconds = Capybara.default_wait_time)

This method is Capybara's primary defence against asynchronicity problems. It works by attempting to run a given block of code until it succeeds. The exact behaviour of this method depends on a number of factors. Basically there are certain exceptions which, when raised from the block, instead of bubbling up, are caught, and the block is re-run.

Certain drivers, such as RackTest, have no support for asynchronous processes, these drivers run the block, and any error raised bubbles up immediately. This allows faster turn around in the case where an expectation fails.

Only exceptions that are ElementNotFound or any subclass thereof cause the block to be rerun. Drivers may specify additional exceptions which also cause reruns. This usually occurs when a node is manipulated which no longer exists on the page. For example, the Selenium driver specifies `Selenium::WebDriver::Error::ObsoleteElementError`.

As long as any of these exceptions are thrown, the block is re-run, until a certain amount of time passes. The amount of time defaults to Capybara.default_wait_time and can be overridden through the `seconds` argument. This time is compared with the system time to see how much time has passed. If the return value of `Time.now` is stubbed out, Capybara will raise `Capybara::FrozenInTime`.

Parameters:

  • seconds (Integer) (defaults to: Capybara.default_wait_time)

    Number of seconds to retry this block

Returns:

  • (Object)

    The result of the given block

Raises:



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/capybara/node/base.rb', line 73

def synchronize(seconds=Capybara.default_wait_time)
  start_time = Time.now

  if session.synchronized
    yield
  else
    session.synchronized = true
    begin
      yield
    rescue => e
      session.raise_server_error!
      raise e unless driver.wait?
      raise e unless catch_error?(e)
      raise e if (Time.now - start_time) >= seconds
      sleep(0.05)
      raise Capybara::FrozenInTime, "time appears to be frozen, Capybara does not work with libraries which freeze time, consider using time travelling instead" if Time.now == start_time
      reload if Capybara.automatic_reload
      retry
    ensure
      session.synchronized = false
    end
  end
end

Comments