Capybara: Test current path to page created object

10,442
expect(current_path).to eq ...

doesn't use Capybara's waiting behavior - which means since click_on is asynchronous (isn't waiting for anything on screen, or for the submit to complete) your test may be very flaky. You're much better off using

expect(page).to have_current_path(expected_path)

since that will use Capybara's waiting behavior while checking for the expected path.

On top of that you have the issue that the LostPet object isn't yet created right after the click_on executes (asynchronous) so calling LostPet.last then will most likely return nil. You have a couple of options here

Wait for some text thats going to appear on the page

expect(page).to have_text('Lost Pet created') # shows in a flash message, or header on the show page, etc
# since you know the show page is visible now you can query for the last LostPet created
expect(page).to have_current_path(lost_pet_path(LostPet.last)) 

or, use the regex option with have_current_path and don't worry about verifying the actual id of the url

expect(page).to have_current_path(/lost_pet\/[0-9]+/) # match the regex to whatever your urls actually are

or something like that

Share:
10,442
Stefan Hansch
Author by

Stefan Hansch

Updated on July 22, 2022

Comments

  • Stefan Hansch
    Stefan Hansch almost 2 years

    After creating new object should redirect to action show. How me check current path?

    feature 'add lost pet' do
      given(:data) {attributes_for(:lost_pet)}
    
      background do
        visit  root_path
        click_on 'Register new lost pet'
      end
    
      scenario 'add new lost pet with valid data' do
        within '#new_lost_pet' do
          fill_in 'Name', with: data[:name]
          fill_in 'Type', with: data[:type]
          fill_in 'Breed', with: data[:breed]
          fill_in 'Gender', with: data[:gender]
          fill_in 'Size', with: data[:size]
          fill_in 'Colour', with: data[:colour]
          fill_in 'Age', with: data[:age]
          fill_in 'Age unit', with: data[:age_unit]
          fill_in 'Description', with: data[:description]
          fill_in 'Collar description', with: data[:collar_description]
          check 'Desexed', :checked
          check 'Microchipped', :checked
          fill_in 'Microchip number', with: data[:microchipped_number]
          select '2015', from: "lost_pet[date_missing(1i)]"
          select 'October', from: 'lost_pet[date_missing(2i)]'
          select '10', from: 'lost_pet[date_missing(3i)]'
          fill_in 'Rewald', with: data[:rewald]
          fill_in 'Image', with: data[:image]
          fill_in 'Adress lost', with: data[:adress_lost]
    
          click_on 'Create'
        end  
    
        expect(current_path).to eq lost_pet_path(????)
    
    
      end
    

    For lost_pet_path i need id, but how me create id? Or how better check path in Capybara?

  • Stefan Hansch
    Stefan Hansch over 8 years
    i added lost_pet = LostPet.last and get error: Failure/Error: expect(current_path).to eq lost_pet_path(lost_pet) ActionController::UrlGenerationError: No route matches {:action=>"show", :controller=>"lost_pets", :id=>nil} missing required keys: [:id]
  • Thomas Walpole
    Thomas Walpole over 8 years
    the asynchronous nature of click_on means the LostPet most likely won't have been created at this point (if using any driver other than rack-test) - so LostPet.last will be nil -- see my answer