Reputation: 129
I am trying to test the destroy action of an article with capybara and rspec. In the view file I include an alert for delete link and here is my spec file:
# spec/features/article_view_spec.rb
require 'rails_helper'
describe 'the article view', type: :feature do
let(:article) do
Article.create(title: 'a title', body: 'This is a sample body for a sample article.')
end
before(:each) do
article.reload
visit root_path
end
.
.
.
it 'deletes an article', js: true do
visit article_path(article)
find(:xpath, '//link[@href="/articles/1"]').click
sleep 1.seconds
alert = page.driver.browser.switch_to.alert
expect { alert.accept }.to change(Article, :count).by(-1)
end
but it returns this error:
Failures:
1) the article view deletes an article
Failure/Error: @article = Article.find(params[:id])
ActiveRecord::RecordNotFound:
Couldn't find Article with 'id'=1
# ./app/controllers/articles_controller.rb:9:in `show'
# ------------------
# --- Caused by: ---
# Capybara::ElementNotFound:
# Unable to find xpath "//link[@href=\"/articles/1\"]"
# ./spec/features/article_view_spec.rb:40:in `block (2 levels) in <top (required)>'
Finished in 4.68 seconds (files took 1.83 seconds to load)
5 examples, 1 failure
Failed examples:
rspec ./spec/features/article_view_spec.rb:38 # the article view deletes an article
by the way I use the selenium-webdriver. what's the problem?
Upvotes: 2
Views: 1046
Reputation: 49950
Since this is a JS test and it's failing on the show page for the model, it's most likely you have not configured for truncation mode and are still using transaction mode. Transaction mode doesn't work for tests using anything but the rack-test driver because each thread has it's own database connection which doesn't know about transactions cached in the other thread connection. See - https://github.com/DatabaseCleaner/database_cleaner#rspec-with-capybara-example
Secondly, lets rewrite the test to use the Capybaras modal API and click link, rather than an unnecessary xpath, to make it easier to read and understand
it 'deletes an article', js: true do
visit article_path(article)
expect {
accept_alert do
click_link('', href: "/articles/1").click
end
sleep 1 #needed because click_link doesn't wait for side effects to occur, although it should really be an expectation to see something that changes on the page after the article is deleted
}.to change(Article, :count).by(-1)
end
Upvotes: 2