简体   繁体   中英

Tests UJS Rails with Capybara, Selenium and Rspec

On my page I have :

-->a form that scrapes the content of another website with a Ajax request made with ujs ( remote: true ):

<%= simple_form_for @listing, :url => listings_fetch_url, remote: true do |f| %>
  <%= f.input :url %>
  <%= f.button :submit, id: 'import_button' %>
<% end %>

-->another form that is populated by the scraping results from the form above

Manually it works...

However when I'm trying to automatically test it , it doesn't. Capybara finds the submit button, clicks on it but then it leaves me on a blank page.

Here is the code for the test :

feature "Listing import" do
  scenario "fills in the form fields", js: true do
    visit new_search_path
    fill_in 'Url', :with => 'www.google.fr'

    find('input#import_button').click

    expect(page.body).to have_content 'query was'
  end
end

The controller actions are the following:

def fetch
    url = listing_params[:url] 
    @query = Query.new(ScraperService.new({url: url}).perform)
    render :fill
end

# Renders an js.erb file
def fill
end

It seems like rspec with selenium can't render js.erb files?

Any help is appreciated!

EDIT

Thanks to @ThomasWalpole, I fixed an error 500 which was preventing Mechanize to scrape the web. The content is now scraped correctly but the problem remains: the page after clicking on the submit button becomes blank and the tests ends right afer. In the logs I have a lengthy message :

Could not log "render_template.action_view" event. NoMethodError: undefined method example_group' for nil:NilClass ["/Users/Greg/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/rspec-rails-3.6.0/lib/rspec/rails/view_rendering.rb:67:in current_example_group'"

Which seems to be the same problem as : 1 & 2

Solved it!

The problem came from the fact that my js.erb wasn't adding a new element on the current page (ie: a new class, a new id, a new DOM element...).

Capybara never waited for the Ajax request to complete!

I appended a new line to my js.erb:

$("#import_button").addClass("imported");

This way I know that when the class imported is present on the current page it means the Ajax request is over.

Then in my test I added the following line:

expect(page).to have_selector :css, '#import_button.imported', wait: 10

Everything works fine now 🤘

PS: this website helped me understand the problem as well

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM