Search code examples
rubyrspeccapybararspec-rails

How to make my RSpec describe blocks run independently of one another?


On my Dashboard page, I have a Metrics section where I show the number of goals a user has. I do not show this section for a user who has no goals. When a user creates a goal and after a redirect the Metrics section will appear.

In the RSpec test below, when RSpec randomly runs the first describe first, the test passes because it does not find the Metrics section. However when RSpec runs the second describe block first, the first describe block fails because by that time the redirect has happened and the Metrics section has appeared.

How do I ensure that each block runs separately and passes?

describe "Dashboard Pages", :type => :request do

  subject { page }
  let(:user) { FactoryGirl.create(:user) }

  before(:each) do 
    sign_in user
  end  

  describe "After user signs in - No Goals added yet" do

    it { is_expected.to have_title(full_title('Dashboard')) }
    it { is_expected.to have_content('Signed in successfully')}

    it "should not show the metrics section" do
      expect(page).to_not have_css("div#metrics")
    end

  end

  #
  #Notice that this runs using the SELENIUM WebDriver
  #
  describe "After user signs in - Add a new Goal" do

    it "should display the correct metrics in the dashboard", js: true do

      click_link "Create Goal"      
      fill_in "Goal Name", :with=> "Goal - 1" 
      fill_in "Type a short text describing this goal:", :with => "A random goal!"
      click_button "Save Goal"
    end  

  end

end

Solution

  • I think your problem is that the request sent by click_button "Save Goal" arrives at the server after that test completes. Capybara's Javascript drivers are asynchronous and don't wait for the commands that they send to the browser to complete.

    The usual way to get Capybara to wait is to expect something about the page that will be true when the command you want to wait for is complete. That's a good idea here anyway since the last test doesn't actually expect that the metrics are shown like it says it does. So expect that they are:

    it "should display the correct metrics in the dashboard", js: true do
      click_link "Create Goal"      
      fill_in "Goal Name", :with=> "Goal - 1" 
      fill_in "Type a short text describing this goal:", :with => "A random goal!"
      click_button "Save Goal"
      expect(page).to have_css("div#metrics")
    end
    

    Also, note that current RSpec and Capybara don't allow you to use Capybara in request specs. Unless you're tied to old versions for some other reason, I suggest upgrading to current RSpec and Capybara and converting your request spec to a feature spec.