Currently writing tests for my Rails app's time tracking functionality. I can't figure out a way to simulate clicking the "play" button on the timer, waiting a few seconds, clicking pause and then submitting the form (creating a new Timestamp object).
test "track time with stopwatch" do
visit new_project_timestamp_path(@project)
find('#play_button').click
sleep 4.0
find('#pause_button').click
click_button "submit_new_timestamp"
visit project_path(@project)
assert page.has_content? "4 seconds"
end
^This is the gist of what I want it to do, but sleep obviously doesn't work because it suspends the thread completely, whereas I want the test to kind of "wait around" while the stopwatch does its thing for a few seconds. The above test fails because no time is actually tracked; pause is clicked immediately after play, in the eyes of the timer, and so the form is submitted with no actual time logged, which of course throws a validation error.
Is there a way I'd be able to simulate waiting a few seconds without actually suspending the thread?
(Note: huge thanks to Tom Walpole for his answer. The issue was that I wasn't using a JS-enabled web driver. Thought I'd write this for anyone else having similar problems due to the same lack of understanding I had.)
The issue is that I wasn't using a web driver that executes Javascript. By default Capybara uses the :rack_test
driver which, while fast, doesn't execute Javascript.
So for integration tests that rely on JS being executed (in my case interacting with a stopwatch), something like :poltergeist
is a good idea. To set it up, add
gem 'poltergeist'
gem 'phantomjs', :require => 'phantomjs/poltergeist'
to the Gemfile and run bundle install
.
You'll need to add
require 'capybara/poltergeist'
Capybara.javascript_driver = :poltergeist
to your test/spec helper file. Then all you need to do is set Capybara.current_driver = Capybara.javascript_driver
wherever you need a JS-enabled integration test.