ruby-on-railsajaxrspeccapybaracapybara-webkit

$.ajax request breaking js: true spec in rspec


I have a spec that passes looking like the following:

scenario "Brand likes a comment", js: true do
  visit post_path(question, as: brand)

  within("#comment_#{comment.id}") do
    click_on "Like"
  end

  expect(page).to have_text "Like •1"
end

I've recently added a page with chart.js graph and I am loading the data for that graph with an ajax request that looks as so:

  $.ajax({
    url: "/admin/reporting/weekly_new_users",
    type: "get",
    dataType: "json",
    cache: false,
    success: function(response){
      var ctx = document.getElementById("weeklyUsers");
      new Chart(ctx, {
          type: 'line',
          data: {
              labels: response.weekly_users.map(arr => arr[0]),
              datasets: [{
                  label: '# of New Users',
                  data: response.weekly_users.map(arr => arr[1]),
                  backgroundColor: [
                      'rgba(255, 99, 132, 0.2)',
                  ],
                  borderColor: [
                      'rgba(255,99,132,1)',
                  ],
                  borderWidth: 1
              }]
          },
      });
    }
  })
};

This ajax request is causing my spec with js:true to fail, with the following error message:

Failure/Error: raise ActionController::RoutingError, "No route matches [#{env['REQUEST_METHOD']}] #{env['PATH_INFO'].inspect}"

     ActionController::RoutingError:
       No route matches [GET] "/likes/1"

When I comment out the ajax request the spec passes. Not sure whats causing this, any ideas?


Solution

  • You've indicated you're using capybara-webkit as your driver for JS tests - If that's actually true, then most likely you're not fully polyfilling and transpiling your JS code to be compatible with it. This ends up meaning you have errors (unsupported JS) in the concatenated assets served to your app which prevents some of the JS from being processed. In this case I'm guessing your Like link/button is normally processed by JS (possibly you've set a method on the link for Rails to use - POST, PUT, PATCH etc) but the errors in the JS are preventing the JS handlers from being attached to the link/button.

    As for what in your $.ajax is causing issues, one possibility is that you're using arrow functions which are not supported by capybara-webkit (it's roughly equivalent to a 6-7 year old version of Safari). In order to continue using capybara-webkit you need to make sure all of your JS is transpiled and polyfilled to be compatible with really old browsers. A MUCH better solution, although possibly more work, is to swap over to using Selenium with headless Chrome or Firefox for your testing. Not only do you get the ability to test on modern browsers your users are actually using, but also the ability to easily swap between headed and headless when trying to debug issues.