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'
, addCapybara.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
Watermark in Existing PDF in Ruby
How to Do Fuzzy Substring Matching in Ruby
Fastest Way to Find a String into an Array of String
"The Ruby Way" (Mixins and Class Reopening) VS. Dependency Injection
How Do Get a Random Datetime Rounded to Beginning of Hour in Rails
Ruby/Rails - How to Create a Class and Access It from the Controller
Rails 3. How to Explicitly Round a Number to Two Decimal Places in The Model
How to Share Worker Among Two Different Applications on Heroku
Ssl Error on Http Post (Unknown Protocol)
Can You Create/Write/Append a String to a File in a Single Line in Ruby
Naming Conventions for Boolean Attributes
Can't Install Rmagick and Imagemagick on Windows 7
Rails Guides Offline Documentation
Best Way to Remove File Extension
How to Get Class-Object from String "A::B::C" in Ruby
Have a Parent Class's Method Access the Subclass's Constants
Factory_Girl + Rspec Doesn't Seem to Roll Back Changes After Each Example