Mock browser time in feature tests

Sometimes it could be necessary to mock your browser time for your tests if your app relies on JS (e.g. if using React).

An example scenario:

scenario "mocking browser time...", :js, :mock_browser_time do
  travel_to Date.new(2017, 6, 1) do
    visit root_path
    ...
  end
end

First, we’ll need to add a couple of helper methods for Capybara:

Capybara.class_eval do
  def self.mock_browser_time(&block)
    @mock_browser_time = true
    yield block
    @mock_browser_time = false
  end

  def self.mock_browser_time?
    @mock_browser_time
  end
end

And then in an around hook for RSpec:

RSpec.configure do |config|
  config.around(:each, :mock_browser_time) do |example|
    Capybara.mock_browser_time { example.run }
  end
end

This will allow us to mock the browser time in our tests if needed using the tag mock_browser_time. The last bit is the code needed for actually mocking the time in the browser. Previous work could be find here

- if Rails.env.test? && defined?(Capybara) && Capybara.mock_browser_time?
  - unix_millis = (Time.now.to_f * 1000.0).to_i

  :javascript
    lolex.install({ now: #{unix_millis}, shouldAdvanceTime: true });

The shouldAdvanceTime option was needed for us, it will depend on your codebase.

Also if your time works in different timezones be sure to add a common timezone for your tests. Add this to your rails_helper file:

ENV["TZ"] = "UTC"

References:

1 Like