Deadlock Detected with Capybara-Webkit

deadlock detected with capybara-webkit

This is happening because you have two threads, the test and the request, modifying the database asynchronously. It looks like you've rightly been experimenting with different configurations in your spec_helper. I've spend a fair amount of time struggling with this same issue, and have come up with this:

# adapted from https://gist.github.com/moonfly/4950750

require 'database_cleaner'

RSpec.configure do |config|

config.use_transactional_fixtures = false

config.before( :suite ) do
DatabaseCleaner.clean_with :truncation
DatabaseCleaner.strategy = :transaction
end

config.around( :each ) do |spec|
if spec.metadata[:js]
# JS => doesn't share connections => can't use transactions
spec.run
DatabaseCleaner.clean_with :deletion
else
# No JS/Devise => run with Rack::Test => transactions are ok
DatabaseCleaner.start
spec.run
DatabaseCleaner.clean

# see https://github.com/bmabey/database_cleaner/issues/99
begin
ActiveRecord::Base.connection.send :rollback_transaction_records, true
rescue
end
end
end

end

I keep it all in support/database_cleaner_configuration.rb, which would work for you, as well, or you can simply replace what you've got in your spec_helper. If this doesn't work, let me know - I have a few other ideas, but they're kookier, and not worth getting into if this works, which it probably will...

Note:

It might be worth mentioning that Rails 5.1+ solves the database problem. Eileen Uchitelle on the Rails team made the changes necessary to run ensure test threads and the Rails server can run in the same process by sharing the database connection.

PG::TRDeadlockDetected: ERROR: deadlock detected

I might have found a solution to my question: I had some queries outside of my controllers (custom middleware), which seem to have caused the problem.

If you have queries outside of controllers (ActiveMailer could also cause this problem), put your code in a ActiveRecord::Base.connection_pool.with_connection block:

ActiveRecord::Base.connection_pool.with_connection do
# code
end

ActiveRecord’s with_connection method yields a database connection from its pool to the block. When the block finishes, the connection is automatically checked back into the pool, avoiding connection leaks.

I hope this helps some of you!

Capybara webkit doesn't pass params from angular

Without seeing all of your code, this feels like it could be a problem associated with a known issue in the capybara-webkit gem is unable to pass entity bodies to the server.

I suspect that the update request is being sent as a PATCH request (which is appropriate), but the issue with the gem results in failure for your tests.

A workaround to your problem is to change the method of the request to PUT or POST, the issue linked above shows some options. You will be able to get your test to pass, but it's up to you to decide if changing the request type is worth getting your test to pass.

Note: In practice it may not matter if you don't actually use PATCH, as you could technically use (some of) the other http methods interchangeably -- but use caution as there are reasons to use a specific http method for a given situation. See this rubyonrails.org post from a few years ago for some details.

have trouble with using capybara-webkit attach_file upload an image

It looks like you're using CSS to overlay another element on top of the HTML input. Some people do this because it's difficult to style HTML file inputs directly. However, doing so breaks capybara-webkit, because it needs to click on the actual HTML input field and the styled element is positioned on top of it.

This is being discussed in a GitHub issue.

You can work around it in the test by using execute_script to hide the overlay element, and then attempting to upload the file.

Capybara-webkit cannot handle link with bootstrap glyphicon

It appears that people work around this by modifying the test to either click the element using javascript or change the opacity of the overlying item. Instead, I went for the following, which is relies more on rails capabilities. I wrote a trash_icon helper as follows:

  def trash_icon
if Rails.env.test?
'proxy_for_trash_icon'
else
"<span class='glyphicon glyphicon-trash'/>".html_safe
end
end

and modified my link to:

link_to trash_icon, feed_item, data: {confirm: 'Are you sure?',toggle: 'tooltip'}, method: :delete, title: 'Delete', id: 'delete_post'

and the test to:

page.accept_confirm do
click_link 'proxy_for_trash_icon'
end

This tests everything except the exact text/icon used in the production system.

Still, hopefully someone will come up with a solution that is not a workaround.

Timing issue with ActionCable, Capybara Webkit, and Capybara Session#window

To test features using RSpec which require ActiveJobs to run I find the following useful - install rspec-activejob, set config.active_job.queue_adapter = :test in your test.rb and then put the following file in your spec/support directory

require 'rspec/active_job'

RSpec.configure do |config|
config.include(RSpec::ActiveJob)

# clean out the queue after each spec
config.after(:each) do
ActiveJob::Base.queue_adapter.enqueued_jobs = []
ActiveJob::Base.queue_adapter.performed_jobs = []
end

config.around :each, perform_enqueued: true do |example|
@old_perform_enqueued_jobs = ActiveJob::Base.queue_adapter.perform_enqueued_jobs
ActiveJob::Base.queue_adapter.perform_enqueued_jobs = true
example.run
ActiveJob::Base.queue_adapter.perform_enqueued_jobs = @old_perform_enqueued_jobs
end

config.around :each, peform_enququed_at: true do |example|
@old_perform_enqueued_at_jobs = ActiveJob::Base.queue_adapter.perform_enqueued_at_jobs
ActiveJob::Base.queue_adapter.perform_enqueued_at_jobs = true
example.run
ActiveJob::Base.queue_adapter.perform_enqueued_at_jobs = @old_perform_enqueued_at_jobs
end
end

which will configure different metadata you can use per test to specify whether or not you want the active jobs created to be executed during your test.

scenario "does something that needs job to run", perform_enqueued: true do
...
end

Rspec Capybara Failure/Error: DatabaseCleaner.clean

Give some time to the database cleaner to do its job !
A dummy way of solving the issue is by using the sleep method like so:
sleep(1), at the begining of each "it" block. That should do the job ✅

What's hapenning is that database cleaner doesn't have the time to clean your PSQL DB that you are already trying to recreate the same instance you used in the previous test.

capybara-webkit cannot simulate click on (non link/button) element

The problems I had and solutions:

1) Capybara trigger() method isn't supported with selenium-webdriver or capybara-webkit.

  • a solution: trigger the jquery event directly from javascript: page.execute_script(%Q($("#... although this isn't as useful as it could fire the event on an element that isn't visible to the user.

2) save_and_open_page doesn't use the asset pipeline, so is fairly useless if you have hidden clickable elements. The poltergeist driver has save_screenshot, which works, but it's not as useful as having a real browser page with the assets loaded

  • a solution: precompile assets in test, although I couldn't get jQuery to load with any driver ($ is undefined) and poltergiest/phantomjs doesn't allow access to local compiled files (passing command line options to the driver has no effect)

  • better solution: use unreleased Capybara 2.1+ gem 'capybara', git: 'git://github.com/jnicklas/capybara.git', add Capybara.asset_host = "http://localhost:3000" to spec_helper.rb and leave dev server running

3) capybara-webkit Error undefined method find_xpath for #<Capybara::Webkit::Driver When using Capybara.javascript_driver = :webkit

  • solution: use master branch
    gem 'capybara-webkit', git: 'git://github.com/thoughtbot/capybara-webkit.git'

My set up in the end was Poltergeist (supports trigger method) + Capybara beta with assets served from dev server (not precompiled) so save_and_open_page works.



Related Topics



Leave a reply



Submit