calebhearth / formulaic Goto Github PK
View Code? Open in Web Editor NEWSimplify form filling with Capybara
License: MIT License
Simplify form filling with Capybara
License: MIT License
Starting with a recent capybara release, using formulaic kicks out deprecation warnings. Example from the formulaic feature spec:
Locator #<Formulaic::Label:0x007fc83c29c4b0 @model_name=:user, @attribute=:name, @action=:new> must be an instance of String or Symbol. This will raise an error in a future version of Capybara.
I ran into this in my own code and then forked and modified the specs here to confirm.
Here's my commit that causes the failing test:
https://github.com/jamesBrennan/formulaic/commit/a79df327a8f6d70ded4f21e8d047ead2618244c3
I don't have time to look at a fix for this right now. If I do start to work on it I'll update this issue.
We inherited the experience pattern from thoughtbot NYC. It is pretty fantastic.
We made a small modification in some of the experiences so we can handle multiple sessions.
class StudentExperience < Experience
def page
@page || begin
Capybara.using_session(:student) do
@page = Capybara.current_session
end
end
end
end
This would allow this specific experience to have it's own session so we could go back and form between two different roles without having to use Capybara.using_session
However by default formulaic uses Capybara.current_session
so if we were to use fill_form
inside an experience it breaks because it looks at the wrong session.
I am willing to put in the work make formulaic work with this pattern but I need some guidance in how you wish this to be coded. Specifically do you want this passed down be default in the DSL#fill_form
then in the Input
just execute all actions off the passed down session?
It seems like a smell to pass the session all the way down but I can't figure out a better way to do it.
For example we have
fill_form(:user, user_attributes)
and this is used in one spec file.
Lets image we have two or three registration forms through devise or any other authentication plugins and in our system we have two registrable resources for example admins and users or three admins, users, members.
So then instead writing this line
fill_form(:user/:admin/:member, user/admin/member_attributes)
in each scenario for per resource I want to declare it once on my shared_example(https://www.relishapp.com/rspec/rspec-core/docs/example-groups/shared-examples) file for example
fill_form(resource, resource_attributes)
By standard way for this purposes I need to create
let(:resource_name) { admin/member/user.class.name.downcase.to_sym }
and pass it to this
fill_form(resource_name, resource_attributes)
Is it possible to add this or it's overhead?
If I call fill_form
with a form name that does not appear on the page, or a field that does not appear on the page, formulaic errors with:
NameError: uninitialized constant Formulaic::InputNotFound
I had following in my spec:
factory :business_details do
name Forgery(:name).company_name
phone Forgery(:address).phone
country Forgery(:address).country
state Forgery(:address).state
city Forgery(:address).city
zip Forgery(:address).zip
address_1 Forgery(:address).street_address
end
fill_form :business_details, attributes_for(:business_details)
It was taking ~10 seconds.
All fields are string inputs except 1 country dropdown.
After refactoring to:
fill_form :business_details, attributes_for(:business_details).except(:country)
select attributes_for(:business_details)[:country], from: 'Country'
It took less than 1 second.
Move to another CI - GitHub maybe? - and update the metrix for currently supported Rubies and Railses
The Fixnum
constant is deprecated in Ruby 2.4, to be replaced with Integer
. This causes a warning to be printed:
/home/mike/.gem/ruby/2.4.0/gems/formulaic-0.3.0/lib/formulaic/form.rb:11: warning: constant ::Fixnum is deprecated
Let's find a way to silence that warning.
Hi, I am trying to integrate Formulaic into my RSpec test suite. But whenever I include the config.include Formulaic::Dsl, type: :feature line in the spec_helper.rb, I am getting the following error.
I am running on Rails 4.2.5.2 and the Formulaic version in 0.3.0. I tried the same with another app running on 4.2.5. It's been the same. It would be really great if someone can point what I am doing wrong.
Thank You.
Here is the trace.
/home/p150/Documents/code/booker/spec/spec_helper.rb:18:in `<top (required)>': uninitialized constant Formulaic (NameError)
from /home/p150/.rbenv/versions/2.3.0/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
from /home/p150/.rbenv/versions/2.3.0/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
from /home/p150/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.3/lib/rspec/core/configuration.rb:1295:in `block in requires='
from /home/p150/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.3/lib/rspec/core/configuration.rb:1295:in `each'
from /home/p150/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.3/lib/rspec/core/configuration.rb:1295:in `requires='
from /home/p150/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.3/lib/rspec/core/configuration_options.rb:109:in `block in process_options_into'
from /home/p150/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.3/lib/rspec/core/configuration_options.rb:108:in `each'
from /home/p150/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.3/lib/rspec/core/configuration_options.rb:108:in `process_options_into'
from /home/p150/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.3/lib/rspec/core/configuration_options.rb:21:in `configure'
from /home/p150/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.3/lib/rspec/core/runner.rb:105:in `setup'
from /home/p150/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.3/lib/rspec/core/runner.rb:92:in `run'
from /home/p150/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.3/lib/rspec/core/runner.rb:78:in `run'
from /home/p150/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.3/lib/rspec/core/runner.rb:45:in `invoke'
from /home/p150/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.3/exe/rspec:4:in `<top (required)>'
from /home/p150/.rbenv/versions/2.3.0/bin/rspec:22:in `load'
from /home/p150/.rbenv/versions/2.3.0/bin/rspec:22:in `<main>'
Hi,
I'm using Formulaic in a project of mine and we use an enum
type for selecting a user's role. Since enum values are of type Symbol
, Formulaic complains with the following error message:
Formulaic does not know how to fill in a Symbol value
My suggestion would be to convert symbol values to strings by calling #to_s
on them and then let StringInput
class handle it as usual. What do you think about this? Can this have any side effects that I'm not seeing right now?
I'd love to send a pull request as we decide on a solution! ๐
Cheers,
Kevin
I love the way formulaic makes my specs read when everything is working, but when I use its DSL and I'm missing some translations or I don't have the parameters quite right, it can be frustrating to figure out why. I find myself source diving formulaic to reverse engineer what went wrong.
I wonder if the InputNotFound
error could be improved to return a list of inputs that were found?
Currently when an input cannot be found it an uninitialized constant Formulaic::InputNotFound
error is being raised.
I found that this https://github.com/thoughtbot/formulaic/blob/master/lib/formulaic/form.rb#L16 enforces consumers to use File
class instance while in rack apps all files are wrapped by http://www.rubydoc.info/gems/rack/Rack/Multipart/UploadedFile
I have an simple_form input that maps to a string attribute, since I want the user to select from fixed options I'm using it as radio_buttons:
<%= s.input :sex, collection: [['M','Male'] ,['F', 'Female']], as: :radio_buttons, label_method: :last, value_method: :first, item_wrapper_class: 'inline', checked: true %>
In my features I have:
fill_form(:student, { name: 'Joe', sex: 'M' })
But capybara isnt beeing able to find it (actually formulaic is not finding it):
**Formulaic::InputNotFound:**
Unable to find input "Sex".
The only way it found it was hard referencing it:
fill_form(:student, {
name: 'Joe',
'enrollment[student_attributes][sex]' => 'M'
})
Hi there!
I wanted to ask if you would be willing to accept a pull request to add instructions on how to setup formulaic
when using Capybara Test Helpers.
It would be a quick snippet:
# test_helpers/base_test_helper.rb
class BaseTestHelper < Capybara::TestHelper
include Formulaic::Dsl
end
or alternatively delegating the needed methods:
# test_helpers/base_test_helper.rb
class BaseTestHelper < Capybara::TestHelper
delegate_to_test_context(:fill_form, :input, :submit, :fill_form_and_submit)
end
Cheers!
I have an ActiveModel class named Credentials
with encapsulates an email and password form. I define the following translations:
---
en:
activemodel:
attributes:
credentials:
email: Email Address
password: Password
However, when I call fill_form(:credentials, { email: '[email protected]', password: 'password' }
, I get an InputNotFound
error. Formulaic first tries to use simple form translations to find the input. Failing that, it tries to get at human attribute name by classify
ing the model name passed to fill_form
. Unfortunately, classify
uses the inflector to singularize the input.
I don't know if there's a great solution to this. I can't think of a scenario where the singularization would be useful for formulaic, but I also think reimplementing classify might be more trouble than its worth here as well.
For now, I can work around this by duplicating the translations as simple_form label translations, but this is also not an ideal solution.
The following name-spaced class:
class Admin::Reservation
# some stuff
end
requires i18n keys such as:
activemodel:
attributes:
admin/reservation:
field: 'Name'
But it seems like formulaic is dropping the namespace.
Example:
We have simple form for user with email field
f.input :email
and we have simple_form.en.yml
labels:
user:
new:
email: 'Enter your email address'
when we try to fill in form like here
fill_form(
:user,
email: email,
password: password
)
then we get error
Formulaic::InputNotFound:
Unable to find input "Email".
so we have to do like here
fill_form(
:user,
'Enter your email address' => email,
password: password
)
I tried using formulaic in my Cucumber steps:
fill_form(:resume, FactoryGirl.attributes_for(:resume))
Getting
undefined method `fill_form' for #Cucumber::Rails::World:0x007f8351584630 (NoMethodError)
Is Cucumber supported at all? If not, will it be supported?
The README says to do click_on submit(:user)
, but submit
isn't a public method (and looks like it may not be a method at all?).
What's the recommended way to submit a form?
When I type fill_form(:user)
, that should function as fill_form(:user, attributes_for(:user))
currently does.
When I type fill_form(:user, :name, :email)
, that should function the same as fill_form(:user, attributes_for(:user).slice(:name, :email))
currently does.
When I type fill_form(:user, :name, password: 'password')
, that should function the same as fill_form(:user, attributes_for(:user).slice(:name).merge(password: 'password'))
currently does.
fill_form("admin.user", terms_and_conditions: true)
Does formulaic support nested forms? Is it going to?
Thanks
When I run the specs locally I get one failure:
Failures:
1) Fill in user form finds and fills a spanish locale date field
Failure/Error: I18n.locale = :es
I18n::InvalidLocale:
:es is not a valid locale
# ./spec/features/fill_in_user_form_spec.rb:88:in `block (2 levels) in <top (required)>'
Master passed 'about a month ago' on Travis, so I assume a gem release since then has caused this breakage. I can't the inspect the Gemfile.lock
created by the CI build to compare against my local version, so I'm not sure how to track down the cause of this.
Fill a form by grabbing keys and values from an attributes hash on an object.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.