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
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.