简体   繁体   中英

Rspec with Capybara sometimes not pass tests

I have problem with testing Rails Application. My tests generally work perfectly. But sometimes tests will fail when I type some features test for modal bootstrap window, or notify with success/error [js]. How can I resolve this problem ? I'm using Rspec, Capybara, Rails4.2, PhantomJs, Poltergeist as JS driver. Tests is running locally and in Wercker. In test mode, every bootstrap animation is disabled. What perhaps I do wrong ? Test:

scenario 'return deutsch default title' do
            find('.f-edit-item', match: :first).click
            find('a', :text => 'Lang').click
            find('a', :text => t('menu.languages.de')).click
            find('.f-reset-button', match: :first).click

            expect(page).to have_field('menu_item[title]', with: 'Exhibitions_de')
          end

Output: Objects Restore Language restore title translations exist for deutsch translation return deutsch default title Failure/Error: expect(page).to have_field('object_item[title]', with: 'Exhibitions_de') expected to find field "object_item[title]" with value "Exhibitions_de" but there were no matches. Also found "", "", which matched the selector but not all filters. Objects Restore Language restore title translations exist for deutsch translation return deutsch default title Failure/Error: expect(page).to have_field('object_item[title]', with: 'Exhibitions_de') expected to find field "object_item[title]" with value "Exhibitions_de" but there were no matches. Also found "", "", which matched the selector but not all filters. When I click manually, everything is working. When I run this test, sometimes passed, sometimes not. Form is in bootstrap modal. Curiosity: When I add save_and_open_page before find('.f-reset-button', match: :first).click test is passed always(5x in a row)

Because the tests are to do with a Bootstrap modal, my guess is that the test is searching the page for the matching elements, BEFORE the modal has loaded in the DOM.

Edit: As @TomWalpole pointed out, it should be enough to override Capybara's max wait time like so:

expect(page).to have_field('menu_item[title]', with: 'Exhibitions_de', wait: 1.0)

But if you are loading the contents of your modal via AJAX, you may need to force a wait for AJAX to complete the expect line. Here is a good guide on how to do this.

Specifically you need:

# spec/support/wait_for_ajax.rb
module WaitForAjax
  def wait_for_ajax
    Timeout.timeout(Capybara.default_wait_time) do
      loop until finished_all_ajax_requests?
    end
  end

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

RSpec.configure do |config|
  config.include WaitForAjax, type: :feature
end

And then your test would become:

scenario 'return deutsch default title' do
  find('.f-edit-item', match: :first).click
  find('a', :text => 'Lang').click
  find('a', :text => t('menu.languages.de')).click
  find('.f-reset-button', match: :first).click
  wait_for_ajax
  expect(page).to have_field('menu_item[title]', with: 'Exhibitions_de')
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM