Sheriff Hussain
Sheriff Hussain

Reputation: 224

Record Deletion testing failure using Capybara with Selenium

My scenario for deletion of a Post record looks like this inside the posts_spec file:

Note: I have set the default transactional fixture property to false, so a Post record is available in the deletion scenario that was created earlier in a create scenario.

RSpec.feature "Signing Post", type: :feature, driver: :selenium_chrome do
  
  scenario "Create Post" do
    ......
  end

  scenario "Delete Post" do
      visit '/posts'
      expect{
        within 'table' do
          accept_confirm do
            find_link(class: ['tester']).click
          end
 
          # When not using sleep, the Post.count is not changed and remains the same
          sleep(1)
    
        end
      }.to change {Post.count}.by(-1)

      expect(page).to have_content("Post was successfully destroyed.")

    end
end

Problem: As you can see that I have used sleep(1) in my code. The reason for doing this was that, without the sleep code, the program seems to not detect that the Record has been deleted. But if I sleep/wait for some time, and then check for the Record, the program now detects that the record has been deleted, and the test runs successfully, as one record has been deleted.

Is it because the accept_confirm action takes some time to process, and we have to wait for confirm to be accepted and then the record to be deleted before asserting any kind of change in the database?

Upvotes: 2

Views: 182

Answers (1)

Thomas Walpole
Thomas Walpole

Reputation: 49870

First, best practices is to have all of your scenarios be independent so they can be run in any order. You have opted to ignore best practices here and made scenarios order dependent - hopefully you have a really good reason for doing that.

As for the sleep being necessary, that is (as your surmised) because browser actions occur asynchronously which means that accepting the confirm returns as soon as the confirm is accepted. It will then take a little time for the deletion request to be processed by your server and the Post.count will be checked before the deletion has actually occurred. To fix that you should be checking for whatever visual change indicates the deletion has occurred. In your case that looks to be the text "Post was successfully destroyed.", so move that inside the Post.count expectation in order to synchronize your test with the application.

expect{
    within 'table' do
      accept_confirm do
        find_link(class: 'tester').click
      end 
    end

    expect(page).to have_content("Post was successfully destroyed.")
  }.to change {Post.count}.by(-1)

Upvotes: 3

Related Questions