Reputation: 2746
I have a page with a link that opens a bootstrap modal with a simple input field. I'm having a hard time understanding why Capybara doesn't wait for the modal to open, and fails immediately.
I added expect(page).to have_content('Did you')
so capybara will wait a few seconds until the modal is shown.
But for some reason it's not waiting and raises Capybara::ExpectationNotMet: expected to find text "Did you" in ...."
If I put a sleep of 1 second it will then find the modal, but it's not good enough because then a DB clean callback found in my spec_helper.rb is called:
config.after(:each) do
DatabaseCleaner.clean
end
This is the spec:
RSpec.describe "follower button", type: :request do
it "sends email #15B to owner", :js do
using_wait_time 20 do
FactoryGirl.create(:apartment_with_event)
visit apartment_path(Apartment.last)
click_on 'follow-events'
expect(page).to have_content('Did you')
within('#follow-events-modal') do
fill_in 'follower-email-signup-mail', with: '[email protected]'
click_button 'follower-signup-submit'
end
expect(page).to have_content(I18n.t("followers.create.title_success"))
expect(Follower.all.count).to eq(1)
end
end
end
I also set Capybara.default_max_wait_time = 10
in spec_helper.rb, even though it should wait for 20 seconds for this example.
Forgot to mention, I'm using Capybara-wekbit as the driver.
I really spent hours trying to discover why it's happening, while other examples run just fine.
UPDATE: Adding full backtrace of failure.
Failures:
1) leeron's button sends email #15B to owner
Failure/Error: raise ActionController::RoutingError, "No route matches [#{env['REQUEST_METHOD']}] #{env['PATH_INFO'].inspect}"
ActionController::RoutingError:
No route matches [GET] "/images/slider/missing.png"
# /Users/etaiso/.rbenv/versions/2.2.3/gemsets/dorbel/gems/rollbar-1.2.13/lib/rollbar/middleware/rails/show_exceptions.rb:22:in `call_with_rollbar'
# /Users/etaiso/.rbenv/versions/2.2.3/gemsets/dorbel/gems/railties-4.2.4/lib/rails/rack/logger.rb:38:in `call_app'
# /Users/etaiso/.rbenv/versions/2.2.3/gemsets/dorbel/gems/railties-4.2.4/lib/rails/rack/logger.rb:20:in `block in call'
# /Users/etaiso/.rbenv/versions/2.2.3/gemsets/dorbel/gems/railties-4.2.4/lib/rails/rack/logger.rb:20:in `call'
# /Users/etaiso/.rbenv/versions/2.2.3/gemsets/dorbel/gems/request_store-1.2.0/lib/request_store/middleware.rb:8:in `call'
# /Users/etaiso/.rbenv/versions/2.2.3/gemsets/dorbel/gems/rack-1.6.4/lib/rack/methodoverride.rb:22:in `call'
# /Users/etaiso/.rbenv/versions/2.2.3/gemsets/dorbel/gems/rack-1.6.4/lib/rack/runtime.rb:18:in `call'
# /Users/etaiso/.rbenv/versions/2.2.3/gemsets/dorbel/gems/rack-1.6.4/lib/rack/lock.rb:17:in `call'
# /Users/etaiso/.rbenv/versions/2.2.3/gemsets/dorbel/gems/rack-1.6.4/lib/rack/sendfile.rb:113:in `call'
# /Users/etaiso/.rbenv/versions/2.2.3/gemsets/dorbel/gems/railties-4.2.4/lib/rails/engine.rb:518:in `call'
# /Users/etaiso/.rbenv/versions/2.2.3/gemsets/dorbel/gems/railties-4.2.4/lib/rails/application.rb:165:in `call'
# /Users/etaiso/.rbenv/versions/2.2.3/gemsets/dorbel/gems/rack-1.6.4/lib/rack/urlmap.rb:66:in `block in call'
# /Users/etaiso/.rbenv/versions/2.2.3/gemsets/dorbel/gems/rack-1.6.4/lib/rack/urlmap.rb:50:in `each'
# /Users/etaiso/.rbenv/versions/2.2.3/gemsets/dorbel/gems/rack-1.6.4/lib/rack/urlmap.rb:50:in `call'
# /Users/etaiso/.rbenv/versions/2.2.3/gemsets/dorbel/gems/capybara-2.7.1/lib/capybara/server.rb:43:in `call'
# /Users/etaiso/.rbenv/versions/2.2.3/gemsets/dorbel/gems/rack-1.6.4/lib/rack/handler/webrick.rb:88:in `service'
# ------------------
# --- Caused by: ---
# Capybara::ExpectationNotMet:
# expected to find text "Did you" in "...(REMOVED BY ME TO SAVE SPACE)..."
# /Users/etaiso/.rbenv/versions/2.2.3/gemsets/dorbel/gems/capybara-2.7.1/lib/capybara/node/matchers.rb:527:in `block in assert_text'
Finished in 3.87 seconds (files took 9.79 seconds to load)
1 example, 1 failure
Upvotes: 0
Views: 1514
Reputation: 49850
From the callback we can see that the actual exception is a routing error from the app. While Capybara is retrying/waiting on finders and expectations it checks for server thrown errors and if Capybara.raise_server_errors
is true it will raise them in the test thread so they are visible to tests. A side-effect of the re-raising of exceptions from the app thread in the test thread is that any current exception in the test thread (such as ExpectationNotMet) which would normally be handled and retried by Capybara gets set by ruby as the nested cause
of the apps exception. It isn't really the cause but we can't because of the way Capybara re-raises the server error it shows up there. You can either set Capybara.raise_server_errors = false
or better yet, fix the missing image.
Upvotes: 2