Capybara::FrozenInTime error in integration specs using Rspec + Timecop + Capybara + Capybara Webkit
Asked Answered
H

2

11

I'm seeing an error in some integration specs, using rspec, capybara, capybara-webkit and timecop.

Capybara::FrozenInTime:
   time appears to be frozen, Capybara does not work with libraries which freeze time, consider using time travelling instead

The only gem that I know that freezes time is Timecop, but I'm not using it in the test case that fails.

Since the error occurs only sometimes I can't even know if its gone or not after changing something.

Highchair answered 21/8, 2012 at 19:8 Comment(2)
This is an awesome error message!Yahiya
I get this error when stubbing Time#now and similar. Switching to Timecop, and making sure Timecop really returns, seems to solve it.Abate
H
6

The solution I found was to add

before :each do
  Timecop.return
end

in spec_helper.rb.

This way we garantee that the time is not frozen before each test, although the only ones that have this problem are the ones executed in a webdriver different from rack-test. In my case capybara-webkit.

Highchair answered 22/8, 2012 at 20:4 Comment(3)
Is it possible you were not adding Timecop.return to an after block for a test where time was being frozen?Yahiya
Well, I suppose I could put Timecop.return in an after block, but Timecop.freeze usually receives a block, that is the proc to be executed with freezed time. Supposedly the time would come back to normal after the block closure.Highchair
You should enable safe mode with Timecop.safe_mode = true in your spec_helper. This will make it so Timecope.freeze requires a block, which means time will be unfrozen for you.Kamasutra
H
11

The end of the error message holds the solution:

consider using time travelling instead

Just change Timecop.freeze to Timecop.travel. Timecop.freeze breaks Capybara's auto-wait feature.

In addition, I would call Timecop.return in an after block, as it will be associated with the most recent travel block:

after :each do
  Timecop.return
end
Hochman answered 2/7, 2013 at 18:17 Comment(1)
The thing is: I really need to freeze time in this case. As a rule of thumb I always use travel, but there are tests that need precision in secondsHighchair
H
6

The solution I found was to add

before :each do
  Timecop.return
end

in spec_helper.rb.

This way we garantee that the time is not frozen before each test, although the only ones that have this problem are the ones executed in a webdriver different from rack-test. In my case capybara-webkit.

Highchair answered 22/8, 2012 at 20:4 Comment(3)
Is it possible you were not adding Timecop.return to an after block for a test where time was being frozen?Yahiya
Well, I suppose I could put Timecop.return in an after block, but Timecop.freeze usually receives a block, that is the proc to be executed with freezed time. Supposedly the time would come back to normal after the block closure.Highchair
You should enable safe mode with Timecop.safe_mode = true in your spec_helper. This will make it so Timecope.freeze requires a block, which means time will be unfrozen for you.Kamasutra

© 2022 - 2024 — McMap. All rights reserved.