Rob
Rob

Reputation: 1855

Capybara error ActiveRecord::StatementInvalid: SQLite3::BusyException: database is locked

I'm testing javascript and I get the following error when I try and submit data to the DB over an ajax form.

ActiveRecord::StatementInvalid:         ActiveRecord::StatementInvalid: SQLite3::BusyException: database is locked: INSERT INTO "check_category_item_keys" ("name", "key_type", "created_at", "updated_at") VALUES (?, ?, ?, ?)

Here is my integration test file

require 'test_helper'

class JavascriptTestingTest < ActionDispatch::IntegrationTest

setup do
    @user = users(:michael)
    @user1 = users(:archer)
    @guide = Guide.find(1)
    @mod_relationship = game_mods_relationships(:mod1)
    @category = Category.find(1)
    Capybara.current_driver = Capybara.javascript_driver # :selenium by default
  end


test "adding keys mod success then fail" do
  log_in_as(@user)
  visit(edit_guide_category_path(@guide, @category))
  itemkeycount = CategoryItemKey.count
  fill_in 'Key name', with: "diablo"
  click_button "Add New Key"  #works fine when this line is removed
end

I'm new to testing JS so I'm guessing there is something more I need to do or something I need to change.

Upvotes: 0

Views: 364

Answers (1)

Thomas Walpole
Thomas Walpole

Reputation: 49890

#click_button does not wait for the results of clicking the button to happen since it has no clue what those will be. So in this case #click_button returns immediately, the test ends, and whatever you're using to clean the database between tests (DatabaseCleaner??) starts cleaning the database. During that time the request triggered by click_button starts to get processed but the cleaning thread has already locked the database (or the other way around) so you get an error. The solution is to have a line that waits for a visible side effect of whatever clicking the button does.

fill_in 'Key name', with: "diablo"
click_button "Add New Key"
assert_text "New Key Added!" # or whatever shows up the page

The assert_text will wait (up to a limit) for that text to appear which should mean the database is no longer in use, the test can finish and cleanup can happen. The other thing to watch for is that you're NOT using transaction based testing since that will also cause you all sorts of issues when doing testing with a JS capable driver - see https://github.com/DatabaseCleaner/database_cleaner#what-strategy-is-fastest

Upvotes: 1

Related Questions