与水豚的存根浏览器时间和时区

use*_*003 3 rspec ruby-on-rails mocking capybara

我有一个严重依赖的JavaScript组件(例如日期选择器)-

  1. 当前系统时间
  2. 当前系统时区

在Ruby和Capybara中,可以借助Timecop之类的库随时进行存根。

是否有可能在Capybara控制的无头浏览器中存入这些值?

谢谢!

编辑:这是一个如何对Ruby进行存根但Capybara的浏览器仍使用系统时间的示例

before do
  now = Time.zone.parse("Apr 15, 2018 12:00PM")
  Timecop.freeze(now)

  visit root_path

  binding.pry
end

> Time.zone.now
=> Sun, 15 Apr 2018 12:00:00 UTC +00:00

> page.evaluate_script("new Date();")
=> "2018-03-27T04:15:44Z"
Run Code Online (Sandbox Code Playgroud)

Tho*_*ole 5

正如您所发现的,Timecop仅影响测试和被测应用程序中的时间。浏览器作为一个单独的进程运行,并且不受Timecop的影响。因此,您还需要使用许多为此设计的JS库之一在浏览器中存根/模拟时间。一个我通常使用的是sinon- http://sinonjs.org/ - ,这我有条件在网页上安装head使用类似

- if defined?(Timecop) && Timecop.top_stack_item
  = javascript_include_tag "sinon.js" # adjust based on where you're loading sinon from
  - unix_millis = (Time.now.to_f * 1000.0).to_i
  :javascript
    sinon.useFakeTimers(#{unix_millis});
Run Code Online (Sandbox Code Playgroud)

这应该在haml模板中有效(如果使用erb,则进行调整),并且在使用Timecop模拟应用程序时间的同时访问页面时,将安装并模拟浏览器时间。

  • 谢谢!`sinon` 非常适合模拟 *时间*,尽管它并没有真正存根浏览器的 *时区*。为此,我必须设置类似 `before(:suite) { ENV['TZ'] = 'America/Los_Angeles' }` 的内容,我测试成功了。问题是它必须位于整个测试套件之前,以便它可以在无头浏览器启动之前运行。如果我想每次测试都运行它,我需要重新启动浏览器本身。水豚中有没有**重启无头浏览器**的好方法?再次感谢您的帮助。 (2认同)

Nor*_*ldt 5

我知道这个问题有点老了,但我们有同样的要求,并找到了以下与 Rails 6 配合使用的解决方案:

context 'different timezones between back-end and front-end' do
        it 'shows the event timestamp according to front-end timezone' do
          # Arrange
          previous_timezone = Time.zone
          previous_timezone_env = ENV['TZ']

          server_timezone = "Europe/Copenhagen"
          browser_timezone = "America/Godthab"

          Time.zone = server_timezone
          ENV['TZ'] = browser_timezone

          Capybara.using_session(browser_timezone) do
            freeze_time do
              # Act
              # ... Code here

              # Assert
              server_clock = Time.zone.now.strftime('%H:%M')
              client_clock = Time.zone.now.in_time_zone(browser_timezone).strftime('%H:%M')
              expect(page).not_to have_content(server_clock)
              expect(page).to have_content(client_clock)
            end
          end
          # (restore)
          Time.zone = previous_timezone
          ENV['TZ'] = previous_timezone_env
        end
end
Run Code Online (Sandbox Code Playgroud)