Spikerr
Spikerr

Reputation: 311

Capybara test doesn't pass with database cleaner, must be run twice without database_cleaner to pass

I am trying to test a dropdown with capybara. It works fine if I don't clean the database. I have to clean the database for other test to function properly.

config.before(:suite) do
    DatabaseCleaner.clean_with(:truncation)
  end
  config.before(:each) do
    DatabaseCleaner.strategy = :transaction
  end
  config.before(:each, js: true) do
    DatabaseCleaner.strategy = :truncation, {:except => %w[questions]}
  end
  config.before(:each) do
    DatabaseCleaner.start
  end
  config.after(:each) do
    DatabaseCleaner.clean
  end

If I comment out the database cleaner the test must run atleast twice to pass. I can see it retry and always pass on the second try with the same criteria. Once the database cleaner is put into place the test paramenters change on each iteration so it doesn't get a chance to test it a second time.

 context 'when there are questions and answers in the system' do
        before do
          allow_any_instance_of(Form).to receive(:create_questions)
          question = create(:question)
          people.map do |person|
            create(:answer, question: question, person: person) if [true, false].sample
          end
        end

        it 'should allow filtering by whether a person has answered a specific question', js: true do
          @question = Question.first
          select_from_dropdown @question.text, from: 'question'
          click_on 'Search'
          people.each do |person|
            if person.questions.include? @question
              expect(page).to have_content person.full_name
            else
              expect(page).to_not have_content person.full_name
            end
          end
        end
      end

This is the helper method which explores the drop down for capybara

  def select_from_dropdown(item_text, options)
    # find dropdown selector
    dropdown = find_field(options[:from], visible: false).first(:xpath, './/..')
    # click on dropdown
    dropdown.trigger('click')
    # click on menu item
    dropdown.find('.menu .item', text: item_text, visible: false).trigger('click')
  end

I have tried sleep throughout the select_from_dropdown thinking that maybe it wasn't loading fast enough but that is not the problem. Ideally this test should work on the first try, but at the very least it needs to pass with the database cleaner.

Upvotes: 0

Views: 91

Answers (1)

Thomas Walpole
Thomas Walpole

Reputation: 49870

There is no visit shown in the test, which means you've visited the page before the questions are created and therefore the info expected is not shown on the page. The data would exist from the first run on the second run if you don't clear the DB which explains why it passes second time around. You should always visit the page after creating the test data.

Additionally as I mentioned in the comments you probably want to fix (remove if using Rails 5.1+) your DatabaseCleaner config and the use of trigger is a really bad idea in tests since it can do things a user never could.

Upvotes: 1

Related Questions