Remove the tedium of formulaic form filling with Capybara.
Formulaic allows you to specify a hash of attributes to be input rather than procedurally calling Capybara’s DSL methods.
gem'formulaic',group: :testfeature'New user registration'doscenario'successfull sign up'dovisitsign_in_pathfill_form(:user,{name: 'Caleb',email: 'caleb@thoughtbot.com','Terms of Service'=>true})click_onsubmit(:user)expect(page).tohave_contentt('user.create.success')endendfill_form(model_name,:new,attributes)fill_form provides an interface to completely filling out a form. Provide the
model_name as a symbol and attributes as a hash of
column name => database value or label string => database value.
If an attributes key is a String, it will be used as the literal label.
For Symbol we will attempt to translate, fall back to human_attribute_name
if available, then call to_s.
input(model_name,field)input gives an easy way to find the translated text of an input. It is
primarily used internally to fill <input>s, but is provided in the public API
as it could be useful.
submit(model_name,:create)submit functions like input, but finds the translation for the
submit button of the form. model_name should be the same as what you provide
to fill_form. Typically, the return value of submit will be
passed directly to Capybara’s click_on method.
If you are submitting a form that is not for the create action, you may need
to pass the action:
submit(:user,:update)The model_name and action should match up to the
helpers.submit.<model_name>.<action> translations.
fill_form_and_submit(:user,:new,attributes)Effectively a fill_form followed by click_on submit, but smart enough to
fill_form with :new and submit with :create and the edit/update cousin.
If you have nested forms, through fields_for (or any variant), you are able to
fill them with an extra call to fill_form.
fill_form(main_model_name,main_model_attributes)fill_form(nested_model_name,nested_model_attributes)# spec/spec_helper.rbRSpec.configuredo |config|
config.includeFormulaic::Dsl,type: :featureend# test/test_helper.rbclassActionDispatch::IntegrationTestincludeCapybara::DSLincludeFormulaic::DslendIntegration with Factory Bot
fill_form(:user,attributes_for(:user))You may have attributes included in your User factory that don’t pertain to
sign up:
fill_form(:user,attributes_for(:user).slice(*sign_up_attributes))# ...defsign_up_attributes[:name,:email,:terms_of_service]endIntegration with Capybara::TestHelper
classBaseTestHelper < Capybara::TestHelperincludeFormulaic::Dslendor alternatively delegate the needed methods:
classFormTestHelper < BaseTestHelperdelegate_to_test_context(:fill_form,:input,:submit,:fill_form_and_submit)endFormulaic relies pretty heavily on the assumption that your application is using
translations for SimpleForm and input helpers, using the
simple_form.labels.<model>.<attribute> and helpers.submit.<model>.<action>
conventions.
You can still use Formulaic by using strings as keys instead of symbols, which
it knows to pass directly to fill_in rather than trying to find a translation.
You’ll need to find submit buttons yourself since submit is a thin wrapper
around I18n.t.
Formulaic assumes your forms don't use AJAX, setting the wait time to 0. This can be configured using:
Formulaic.default_wait_time=5Formulaic currently supports the following mappings from the
#classof the attribute values to Capybara method calls:Classes Formulaic’s action Stringfill_in,choose, orselectDate,ActiveSupport::TimeWithZoneselectyear, month, and dayTrueClasscheckFalseClassuncheckArraycheckorselecteach array member, which should all be strings. If not all items can be selected or checked, an error will be thrown.Fileattach_filewithFile#pathFormulaic is currently tied to
simple_formtranslations and field structure. If you pass a string for the attribute, we’ll try to fill the input that relates to that label. We would be happy to work with you to add support for other form builders.Formulaic currently does not support forms with duplicate labels, as it is designed to be as similar as possible to a user completing a form—it looks at the labels to determine where to fill what data.
Formulaic can’t figure out how to fill fields with HTML labels:
page.fill_in('<strong>Text</strong> here', with: 'something')doesn’t work with Capybara. The usual workaround is to pass a CSS selector (which you can do by passing a string as the attribute key).Formulaic can't handle multiple file attachments on the same input.
Formulaic is maintained by Caleb Hearth and formerly thoughtbot with the help of community contributors. Thank you!

