Thalatta
Thalatta

Reputation: 4578

Capybara::ElementNotFound for AJAX populated <select> option

After getting this error in this previous context, I once again am getting the same error thrown on my test suite. The difference being, that now I am calling a function generate_steps_to_validate_school_pricing which does the following.

def generate_steps_to_validate_school_pricing(school_pricing_hash, school,   homestay_single_room_per_week_cost, airport, airport_price)
  school_pricing_hash.each do |program_name, program |
    prog_name = school + " - " + program_name
    program.each do |price_point_number, price_per_week|
      visit "/application/new"
      fill_in "school_application_first_name", :with => "bob"
      fill_in "school_application_family_name", :with => "balaban"
      check("school_application_sevic") #200 dollars
      select(school, :from => 'school_application_fls_center')
      check('school_application_I_20')
      check('school_application_pay_application_fee_or_full')
      fill_in "school_application_start_date", :with => "05/11/2015"
      select(airport, :from => 'school_application_arrival_airport')
      select('Homestay Single Room', :from => 'school_application_housing_type')
      check("school_application_health_insurance")
      check("school_application_transfer_student")
      fill_in "school_application_comments", :with =>"Lorem"
      fill_in "school_application_gender", :with =>"trans"
      fill_in "school_application_address", :with=> "5/11/15"
      fill_in "school_application_city_state_province", :with =>"Dubai"
      fill_in "school_application_email", :with =>"[email protected]"
      select(airport, :from => 'school_application_arrival_airport')

      fill_in "school_application_postal_code", :with =>"90226"
      fill_in "school_application_country", :with=> "Zimbabwe"
      fill_in "school_application_date_of_birth", :with =>"Dubai"
      fill_in "school_application_phone_number", :with => "2134932434"
      select(price_point_number, :from => "school_application_duration")
      check("school_application_read_everything")
      fill_in "school_application_country_of_birth", :with =>"Aim"
      fill_in "school_application_country_of_citizenship", :with =>"Durango"
      check("school_application_work_with_ad")

      fill_in "school_application_agency", :with =>"Aim"
      fill_in "school_application_fax_number", :with =>"Durango"
      save_and_open_page
      select(prog_name, :from => "school_application_program") # this is the line that fails
      total = price_point_number[0] *price_per_week
      total = total + price_point_number[0] * homestay_single_room_per_week_cost
      total = total + 500 #SEVIS fee (200) + Housing Application and Application Fees (150 each)
      total = total + airport_price
      total = total + 35 * price_per_week[0] #current Insurance for 2015 is 35/week

      click_button "Continue"
      expect(page).to have_text(total.to_s  + " USD")
    end
  end
end

while the sequence of steps defined in the function does not have :js=>true applied, the scenario which makes the call to it does. I am certain that the AJAX calls, in general are working as the tests corresponding to the wother two <select>s that are populated via AJAXs pass.

When I do save_and_open_page the dropdown which should have prog_name is empty, which seems to tell me that for some reason that particular AJAX call is breaking. I am not sure how to test that individual controller method to see what is going on, and am equally unsure of the point of doing that as When I perform the exact same procedure as the Happy Path that I am testing on localhost all of the AJAX calls work perfectly, including populating the <select> that is currently not being populated.

Any notes on how to systematically debug this further would be appreciated. Thank you!

N.B. The issue may very well be that the test does not wait for the Server to respond with the data until it returns the callback. IS there a way to have it wait until the response is received?

UPDATE: Tried extending the Capyabara.default_wait_time to 20 seconds it still failed, which I feel rules out it being a asynchronous problem?

Upvotes: 1

Views: 425

Answers (1)

Thalatta
Thalatta

Reputation: 4578

After thinking this was a Asynchronous issue, I first changed the Capybara wait time for requests, and then finally implemented this much cleaner and reliable solution to guarantee that all asynchronous requests had been completed by following this tutorial: http://robots.thoughtbot.com/automatically-wait-for-ajax-with-capybara

So after implementing the helper function, I know knew for certain it wasn't an Asynchronous issue which meant that there must be some problem with the AJAX call itself. Because it worked in my local server, I did not understand how it would fail when testing the exact same feature but with RSpec .

When I revisited my JS I saw that I had made the following call to the server, for the method that was failing:

    $.ajax({
    url: "http://0.0.0.0:3000/application/get_programs_for_center",
    type: "POST",
    datatype: 'json',
    data: formdata,
    success: function(response){
      var options = $("#school_application_program");
      removeOptions(document.getElementById("school_application_program"));
      $.each(response.programs, function(i,item) {
        options.append($("<option />").val(response.programs[i].id).text(response.programs[i].name));
      });
    }
});

By giving the full path of my local server, it successfully would make the requests locally when I manually tried the same behavior but failed for obvious reasons when I ran bundle exec rspec (which uses a different server) the request failed. The other similar AJAX requests that I wrote all called the relative path and therefore were successful.

Upvotes: 1

Related Questions