Ahmad
Ahmad

Reputation: 129

Deleting test with capybara and rspec fails

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

Answers (1)

Thomas Walpole
Thomas Walpole

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

Related Questions