Capybara synchronize with has_no_css?

前端 未结 3 1363
耶瑟儿~
耶瑟儿~ 2020-12-20 03:36

Since upgrading to Capybara 2.4, I\'ve been running into this issue. Previously, this block worked fine:

page.document.synchronize do
  page.should have_no_c         


        
3条回答
  •  渐次进展
    2020-12-20 04:21

    The have_no_css matcher already waits for the element to disappear. The problem seems to be using it within a synchronize block. The synchronize method only re-runs for certain exceptions, which does not include RSpec::Expectations::ExpectationNotMetError.

    Removing the synchronize seems to do what you want - ie forces a wait until the element disappears. In other words, just do:

    page.should have_no_css('#ajax_indicator', :visible => true)
    

    Working Example

    Here is a page, say "wait.htm", that I think reproduces your problem. It has a link that when clicked, waits 6 seconds and then hides the indicator element.

    
      
        wait test
        
      
    
      
        
    indicator
    hide indicator

    The following spec shows that by using the page.should have_no_css without manually calling synchronize, Capybara is already forcing a wait. When waiting only 2 seconds, the spec fails since the element does not disappear. When waiting 10 seconds, the spec passes since the element has time to disappear.

    require 'capybara/rspec'
    
    Capybara.run_server = false
    Capybara.current_driver = :selenium
    Capybara.app_host = 'file:///C:/test/wait.htm'
    
    RSpec.configure do |config|
      config.expect_with :rspec do |c|
        c.syntax = [:should, :expect]
      end
    end
    
    RSpec.describe "#have_no_css", :js => true, :type => :feature do
      it 'raise exception when element does not disappear in time' do
        Capybara.default_wait_time = 2
    
        visit('')
        click_link('hide indicator')
        page.should have_no_css('#ajax_indicator', :visible => true)
      end
    
      it 'passes when element disappears in time' do
        Capybara.default_wait_time = 10
    
        visit('')
        click_link('hide indicator')
        page.should have_no_css('#ajax_indicator', :visible => true)
      end
    end
    

提交回复
热议问题