Как заставить работать javascript в тесте Rspec Capybara - PullRequest
0 голосов
/ 20 февраля 2019

Я строю простой Reddit Clone для практики и хотел бы проверить, работает ли ajax и правильно ли значение на экране обновляется ответом javascript.Вот тест:

RSpec.describe "User voting", type: :system, js: true do # Rails 5 uses describe, Rails < 5 feature
    it "updates the downvote count" do
        user = create(:user)
        login_as(user)
        link = create(:link)
        visit root_path
        expect(page).to have_css('#upvotes-1', text: '0')
        click_on(id: 'upvoter-1')
        wait_for_ajax
        expect(page).to have_css('#upvotes-1', text: '1')
   end
end

wait_for_ajax: (в /spec/support/wait_for_ajax.rb)

module WaitForAjax
    def wait_for_ajax
        Timeout.timeout(Capybara.default_max_wait_time) do
            loop until finished_all_ajax_requests?
        end     
    end

    def finished_all_ajax_requests?
        page.evaluate_script('jQuery.active').zero?
    end
end

Относительный код из index.html.erb:

<%= button_tag(class: "btn btn-secondary btn-sm", id: "upvoter-#{link.id}") do %>
 <span class="fa fa-chevron-up"></span>
 Upvote
 <%= content_tag(:span, link.upvotes(), id: "upvotes-#{link.id}") %>
<% end %>   

Код контроллера:

  def create
    @vote = current_user.votes.new(link_params)
    if @vote.vote_value == 1
      @new_value = @vote.link.upvotes
      @id_name = "#upvotes-" + @vote.link.id.to_s
    else
      @new_value = @vote.link.downvotes
      @id_name = "#downvotes-" + @vote.link.id.to_s
    end

    respond_to do |format|
      if @vote.save
        format.js   { }
      else
        format.html { render :new }
      end
    end
  end

И, наконец, create.js.erb:

console.log("create.js.erb file");

$("<%= j @id_name %>").html("<%= j @new_value.to_s %>");

Gemfile:

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug'
  gem 'rspec-rails'
  gem 'guard-rspec', require: false
  gem 'factory_bot_rails', '~> 4.0' 
  gem 'database_cleaner'
  gem 'rails-controller-testing'
  gem 'capybara', '~> 2.13'
  gem 'selenium-webdriver'
  gem 'chromedriver-helper'
  gem 'puma'
  gem 'poltergeist'
end

Если я сам загружаю сайти нажмите на кнопку, чтобы счет обновился правильно.Тем не менее, тест не проходит на втором ожидании.Если я перезагрузлю страницу, счетчик обновится, поэтому база данных обновится, и #create будет работать, как и ожидалось.Javascript по какой-то причине не выполняется.И я попытался заснуть после click_on.Это все еще не удается.Кажется, здесь есть что-то простое, чего мне не хватает.

1 Ответ

0 голосов
/ 21 февраля 2019

Переключение на Selenium помогло мне увидеть проблему более четко.Вот довольно хороший учебник, в котором рассказывается, как настроить Rails 5 / последние версии (конец 2018 года):

Краткое руководство по тестированию системы Rails в RSpec

В конце концов, я использовал .new для создания модели, но не сохранил ее, поэтому новый счетчик голосов не показывался.Перемещение логики, которая потянула счет после сохранения, решило проблему.

In voice_controller.rb:

  def create
    @vote = current_user.votes.new(link_params)
    respond_to do |format|
      if @vote.save
        format.js   {
          if @vote.vote_value == 1
            @new_value = @vote.link.upvotes
            @id_name = "#upvotes-" + @vote.link.id.to_s
          else
            @new_value = @vote.link.downvotes
            @id_name = "#downvotes-" + @vote.link.id.to_s
          end             
            }
     else
       format.html { render :new }
     end
   end
  end
...