Some of my feature specs are failing intermittently. Our specs are setting the base-line to be in the past. I have found the following:
- Error thrown is:
UncaughtThrowError (uncaught throw :warden):
[#B3FBC85E07A6] devise (4.3.0) lib/devise/hooks/timeoutable.rb:26:in 'throw'
[#B3FBC85E07A6] devise (4.3.0) lib/devise/hooks/timeoutable.rb:26:in 'block in '
[#B3FBC85E07A6] warden (1.2.7) lib/warden/hooks.rb:15:in 'block in _run_callbacks'
[#B3FBC85E07A6] warden (1.2.7) lib/warden/hooks.rb:10:in 'each'
[#B3FBC85E07A6] warden (1.2.7) lib/warden/hooks.rb:10:in '_run_callbacks'
[#B3FBC85E07A6] warden (1.2.7) lib/warden/manager.rb:52:in '_run_callbacks'
[#B3FBC85E07A6] warden (1.2.7) lib/warden/proxy.rb:180:in 'set_user'
[#B3FBC85E07A6] warden (1.2.7) lib/warden/test/helpers.rb:21:in 'block in login_as'
[#B3FBC85E07A6] warden (1.2.7) lib/warden.rb:40:in 'block in test_mode!'
[#B3FBC85E07A6] warden (1.2.7) lib/warden/hooks.rb:15:in 'block in _run_callbacks'
[#B3FBC85E07A6] warden (1.2.7) lib/warden/hooks.rb:10:in 'each'
[#B3FBC85E07A6] warden (1.2.7) lib/warden/hooks.rb:10:in '_run_callbacks'
[#B3FBC85E07A6] warden (1.2.7) lib/warden/manager.rb:52:in '_run_callbacks'
...
- only fails where I use Timecop
Looking at the error (exception was thrown in timeoutable.rb) and the common use of Timecop, I figured that is what is responsible - but I cannot explain why it is happening nor why it is intermittent.
Here is a sample piece of code to further explain the problem:
Timecop.travel(10.weeks.from_now) do sign_in(user) visit some_path expect(page).to have_title('something') # ... and more end
Notice that the error still shows up sometimes despite signing in after time-travel.
Everything works fine normally, in fact this test (and a couple of other ones) fail 1 in every 50+ times at most.
Any help is much appreciated. Thanks in advance.
EDIT: error occurs when visitng a page, as per screenshot. This screenshot is from a Capybara fail, right after I attempt to visit a page.
I'm guessing the error you're getting is caused by secondary requests the page issues when you visit it. There is a slight time between when
Timecop
resets the time and the test is cleaned up where a request from the page could hit the server and be processed with a session cookie that is invalid (due to the server time having changed). Once you confirm the page is issuing additional requests when you visit it, there are a few things you could do to work around the error.Add an additional
expect
to the test for whatever the additional request(s) are gettingSet
Capybara.raise_server_errors = false
for the specific tests, so the server errors get ignoredImplement a way (possibly middleware) to set
request.env["devise.skip_timeout"] = true
during the specific testsUse the non block version of
Timecop.travel
and then callTimecop.return
in anappend_after
block for the specific tests. This should move the call toreturn
until after Capybara has waited for all requests to finish -- might have potential side effects on the test cleanup though, not 100% sure this would be stable.