Jezen Thomas
Jezen Thomas

Reputation: 13800

Cucumber/Capybara tests fail without save_and_open_page

I have a Cucumber feature with matching step definitions like the following:

Feature:

Feature: Time reporting

  @javascript
  Scenario: User reports billable time with valid data
    * I am signed in
    * the project I worked on exists in the system
    * I report 3 hours of work on the project
    * 3 hours should be logged in the system

Steps:

Given(/^the project I worked on exists in the system$/) do
  @company = FactoryGirl.create :company
  @project = FactoryGirl.create :project, company: @company
end

When(/^I report (\d+) hours of work on the project$/) do |hours|
  visit "/time-reporting/#{Date.today}"
  select_from_chosen @company.name, from: "company_id"
  select_from_chosen @project.name, from: "time_entry_project_id"
  page.evaluate_script("document.querySelector('#time_entry_hours').value = #{hours}")
  click_on "Report"
end

Then(/^(\d+) hours should be logged in the system$/) do |hours|
  #save_and_open_page
  expect(TimeEntry.last.hours).to eq hours.to_f
end

This fails because, even though I’m saving the TimeEntry model in TimeEntriesController, the call to TimeEntry.last fails. It seems the model was not persisted.

If, however, I uncomment save_and_open_page, the assertion works because it has now magically found the model.

What is this voodoo?

Edit:

I suspect this has something to do with Capybara-Webkit. If I interact with the page in some way, like this:

  expect(page.has_content?("3.0 hours were logged.")).to be true

…and I run the model assertion directly after it, then both assertions work just fine.

Upvotes: 1

Views: 255

Answers (1)

Dave Schweisguth
Dave Schweisguth

Reputation: 37617

I've seen save_and_open_page fix tests with poltergeist as well as with capybara-webkit. That happened because save_and_open_page took enough time for the browser to finish doing what it was doing before the test checked that it had completed. The fix was to wait for the condition to become true. Example here: https://stackoverflow.com/a/23555725/634576

As you discovered, you can also wait by asserting content on the page (capybara's has_content waits for the content to appear), and, from the point of view of an acceptance test, that's probably a better thing to do than looking in the database anyway.

Upvotes: 1

Related Questions