Search code examples
rubyunit-testingrspeccapybarapoltergeist

Can I eliminate multiple within_frame calls when writing rspec tests for my site?


I'm writing tests for a legacy app using Capybara + Rspec, and I'm finding that all of my tests need to be run within a specific frame. I've written up a little rspec helper that I run before every test to confirm I'm getting the session set correctly, and then visit the URL:

def set_session
    Capybara.register_driver :poltergeist do |app|
      Capybara::Poltergeist::Driver.new(
          app,
          window_size: [1280, 1024] ,
          timeout: 60 
         )   
    end
    Capybara.javascript_driver = :poltergeist

    @sess = Capybara::Session.new :poltergeist
    #authentication stuff here...
end

describe 'initiate_requests' do
  before(:all) do
    set_session
  end

  before(:each) do
    @sess.visit(URL)    
  end


  it 'shows error if not degree seeking student' do
    @sess.within_frame(FRAME) {
      set_test_vars(FAILID)
      expect(@sess).to have_selector("#NO_PROGRAM_ERROR")
      expect(@sess).not_to have_selector("#submitButton")
    }
  end

  it 'works for a degree seeking student' do
    @sess.within_frame(FRAME) {
      set_test_vars(VALIDID)
      expect(@sess).not_to have_selector("#NO_PROGRAM_ERROR")
      expect(@sess).to have_selector("#submitButton")
    }
  end
end

This works just fine. However, every single test I need to write in the form:

      it 'works for a degree seeking student' do
        @sess.within_frame(FRAME) {
          #do tests..
        }
      end

Is there some way I can in reset the @sess to just work within the frame all the time? Lacking that, is there some way I can declare the @sess.within_frame(FRAME) just once and have all of the tests follow that declaration?


Solution

  • I haven't specifically tried it, but you can probably use an around hook rather than your before(:each) hook

    around(:each) do |example|
      @sess.visit(URL)
      @sess.within_frame(FRAME) do
        example.run
      end
    end