Rails: как я могу протестировать секундомер в моих интеграционных тестах Capybara?

В настоящее время пишу тесты для функции отслеживания времени моего Rails-приложения. Я не могу найти способ имитировать нажатие кнопки "Воспроизвести" на таймере, подождать несколько секунд, нажать "Пауза", а затем отправить форму (создание нового объекта Timestamp).

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

^ Это суть того, что я хочу сделать, но сон, очевидно, не работает, потому что он полностью приостанавливает поток, тогда как я хочу, чтобы тест как бы "подождал", пока секундомер делает свое дело в течение нескольких секунд. Вышеуказанный тест не пройден, потому что время фактически не отслеживается; Пауза щелкается сразу после воспроизведения, в глазах таймера, и поэтому форма отправляется без фактического зарегистрированного времени, что, конечно, вызывает ошибку проверки.

Есть ли способ, которым я мог бы имитировать ожидание несколько секунд, фактически не приостанавливая поток?

2 ответа

Решение

(Примечание: огромное спасибо Тому Уолполу за его ответ. Проблема заключалась в том, что я не использовал веб-драйвер с поддержкой JS. Думаю, я напишу это для тех, у кого есть подобные проблемы из-за того же недостатка понимания, что и у меня.)

Проблема в том, что я не использовал веб-драйвер, который выполняет Javascript. По умолчанию Capybara использует :rack_test Драйвер, который, хотя и быстрый, не выполняет Javascript.

Так что для интеграционных тестов, которые основаны на выполнении JS (в моем случае взаимодействие с секундомером), что-то вроде :poltergeist хорошая идея Чтобы настроить его, добавьте

  gem 'poltergeist'
  gem 'phantomjs', :require => 'phantomjs/poltergeist'

в Gemfile и запустить bundle install,

Вам нужно будет добавить

  require 'capybara/poltergeist'
  Capybara.javascript_driver = :poltergeist

в ваш вспомогательный файл test/spec. Тогда все, что вам нужно сделать, это установить Capybara.current_driver = Capybara.javascript_driver везде, где вам нужен интеграционный тест с поддержкой JS.

Предполагая, что вы используете JS-совместимый драйвер (selenium, poltergeist, capybara-webkit), тогда браузер, тестируемое приложение и тесты выполняются в своих собственных потоках / процессах, поэтому сон в вашем тестовом потоке должен быть идеальным. Вместо того, чтобы отправлять оба клика без разницы во времени, более вероятно, что ваш click_button отменяется visit сразу после него, и поэтому вы не получите новую метку времени. Вы должны заявить о каких-то видимых изменениях между click_button и visit, чтобы убедиться, что создание нового действия с отметкой времени завершено, прежде чем сообщить браузеру запросить новую страницу.

click_button "submit_new_timestamp"
page.assert_text "Timestamp created" # whatever message/visible change occurs after clicking the button
visit project_path(@project)

Кроме того, использование сопоставлений assert_text, assert_selector, assert_title, assert_current_path предоставит вам лучшие сообщения об ошибках, когда утверждения не пройдены, чем утверждение на has_xxx? методы

Другие вопросы по тегам