0
votes

I am writing a RSpec Capybara test for a Rails 5 application. My application is for students learning how to write HTML and CSS. The application creates "test" objects, and then allows the user to take a test. Each time the user answers a question correctly, the app adds to the test object's "score" attribute. At the end, the application gives the user a final score and then records the test result.

I am having my Capybara tests fail because they can not locate a button. The way my app works, the user answers a question and then clicks the "Submit" button. ONLY after they submit an answer, a SECOND button appears that says "Next Question."

My test can not find that second button. I'm not an expert at testing and could use some help. I tried "sleep 5" but it didn't work.

Here is the error:

1) taking test with incorrect answers Failure/Error: click_button 'Next Question'

 Capybara::ElementNotFound:
   Unable to find button "Next Question"
 # ./spec/features/taking_test_spec.rb:12:in `block (2 levels) in <top (required)>'

Here is my test:

require 'rails_helper'

feature "taking test" do 

    scenario "with incorrect answers" do 
        visit '/'
        click_link "HTML Test"
        click_button "Start"
        fill_in "answer", with: '<p>'
        click_button 'Submit'
        sleep 5
        click_button 'Next Question'
        expect(page).to have_content('CSS helps you control the appearance of HTML elements.')
    end

end  

Here is the relevant portion of the controller for tests:

class TestsController < ApplicationController
before_action :authenticate_user!, only: [:destroy]

def index 
    @test = Test.new 
    @tests = Test.all.order(created_at: :desc).paginate(:page => params[:page], :per_page => 4)
end 

def question1 
    @test = Test.find(params[:id])
    correct_answer = "<p>"
    user_answer = params[:answer]
    if user_answer == correct_answer
        flash.now[:success] = "That is correct!"
        new_score = @test.score += 1
        @test.update(score: new_score)
    elsif params[:answer].present? && params[:answer] != correct_answer
        flash.now[:danger] = "Wrong answer." 
    end
end

Here is the view for question1, including the button that Capybara can not find:

<div class="container-fluid">

    <div class="row background-white">
        <div class="col-md-8 col-md-push-2 score_container">
            <h5 class="text-center">Current Score: <%= @test.score %></h5>
        </div>

        <div class="col-sm-6 col-sm-push-3 col-xs-10 col-xs-push-1 question_container">
            <div class="form_group">
            <%= form_tag question1_path(@test), method: :get do %>
                <h5>1. How do you write an opening paragraph tag in HTML?</h5>
                <div class="form-group">
                    <%= text_area_tag :answer, params[:answer], class: 'form-control', id: 'answer' %>
                </div>
                <% if !flash[:success] && !flash[:danger] %>
                <div class="form-group">
                    <%= submit_tag "Submit", class: "btn btn-primary" %>
                </div>
                <% end %>
            <% end %>
            </div>

            <% if flash[:success] || flash[:danger] %>
                <%= link_to "Next Question", question2_path(@test), class:"btn btn-success pull-right" %>
            <% end %> 
        </div>
    </div>
</div> 
1

1 Answers

1
votes

Your Next Question is not a button, it's a link ( <a> element with href attribute - that happens to be styled to look like a button, but it's not a button). Capybara defines a button as input [of type submit, reset, image, button] or button element. You need to use click_link to click a link, or click_link_or_button if you don't care which it is.

visit '/'
click_link "HTML Test"
click_button "Start"
fill_in "answer", with: '<p>'
click_button 'Submit'
click_link 'Next Question'
expect(page).to have_content('CSS helps you control the ap