Is it possible to use Minitest and Capybara to test multi-step forms in Rails? All of the examples I've read online and in Stackoverflow are using Rspec. For instance, this question.
It seems like this should be something that is possible to do in Minitest though. I'm trying to test a nested form that uses the Cocoon gem and looks like this:
Before clicking the "New Option" button:
After clicking the "New Option" button:
But, my test keeps failing at this step:
click_link 'New Option'
If I add 'save_and_open_page' after click_link 'New Option'
the browser shows that field that should be revealed by click_link 'New Option'
. It works when I test it manually on my development server though. This New Option
button is generated by Cocoon with this:
<%= link_to_add_association 'New Option', f, :options %>
So that leads me to believe that it's not finding the field on the next step because javacript is not working in Capybara and Minitest. But I'm not sure.
I have Capybara.javascript_driver = :webkit
in my test_helper.rb
file, so the javascript driver should be working
Is this a problem with Minitest? Or am I doing something wrong in my test? If I view source on the page that is generated by save_and_open_page
I can see the hidden fields in the New Option
link tag. Here's what that looks like:
Based on this question, it seems like I need to do something like this:
click_link "New Option" first("input[name='product[options_attributes][new_options][name]']").set("New Option Name")
But that gives me the error:
Capybara::ExpectationNotMet: expected to find css "input[name='product[options_attributes][new_options][name]']" at least 1 time but there were no matches
It seems like there's something wrong with Minitest & Capybara testing Javascript because it seems to fail at the "New Option" link and not after that. I can't tell if it's a problem with Javascript related to Minitest and Capybara or if I'm not accessing the field properly in Minitest.
Thanks to Thomas Walpole for pointing out that capybara-webkit
was the problem. Along with some help from this article, here's what I needed to change the test passing:
Added these to my Gemfile
:
group :test do
gem 'selenium-webdriver'
gem 'webdrivers'
end
Added this to my test_helper.rb
:
class ActionDispatch::IntegrationTest
Capybara.register_driver :selenium do |app|
Capybara::Selenium::Driver.new(app, browser: :chrome)
end
Capybara.javascript_driver = :chrome
Capybara.configure do |config|
config.default_max_wait_time = 10 # seconds
config.default_driver = :selenium
end
end
And then my test:
test 'Account owners can add a new product as well as options and choices' do
visit new_product_path(as: @account_owner)
assert_title 'Add New Product'
assert_selector 'h1', text: 'Add New Product'
fill_in 'product_name', :with => @new_product.name
# Users can add product options through the nested form
click_link 'New Option'
within('.product_options_name') do
first('input.form-control').set("#{@t_shirt_colors.name}")
end
click_link 'Add Choice'
within('.product-option-choice') do
first('input.form-control').set("#{@red_color_choice.name}")
end
click_button 'Create Product'
assert_selector '.alert', text: 'Product was successfully created.'
end