Search code examples
ruby-on-railscapybararspec-rails

What is the correct usage of capybara's within method?


For feature examples for the footer I've used this code:

feature 'in footer' do
    scenario "has a Copyright text" do
      within('footer') {
        expect(page).to have_content "Copyright"
      }
    end

    scenario "has navigation bar" do
      within('footer') {
        expect(page).to have_selector 'nav ul li'
      }
    end

    scenario "has a link for 'About'" do
      within('footer') {
        expect(page).to have_link 'About', href: '#'
      }
    end
end

If you look closely I repeated the "within" in each scenario and this conflicts with dryness of code.

I do not want to include all expectation in one scenario because I want an explanation for each of them.

What is the best method for using the within method in this situation?


Solution

  • There is no way to dry up the use of #within and still have multiple scenarios. Someone might try to use an around filter, but because of the ordering of around and before/after filters it's not really going to work. You can get what you're looking for without using #within, by finding the footer in a before block and then expect off that

    before do
      visit('my page')
      @footer = find('footer')
    end
    
    scenario 'blah blah' do
      expect(@footer).to have_content('...')
    end
    

    I will say that writing feature tests only to check for a line of text on the page is not great practice. Feature tests have a lot of overhead, and checking for a line of text thats not dependent on any user actions is really more suited to a view test rather than feature (You can still use Capybaras matchers in view tests). Feature tests should be for testing larger behaviors in the system.