Since the introduction of Hpricot, the snazzy and fast Ruby parser for HTML, I've been meaning to give it a whirl - the API looks yummy. Now, as I'm doing more testing and validation stuff at work, such a need has come. Back in Javaland, when I need to navigate or test web apps by code, submit forms and do other web bot stuff, I turn to HtmlUnit. The api is simply awesome and won me over immediately. So if you're still stuck in Java, do give it a look.
Anyways, though the whole testing harness of Rails is a godsend, I started to miss some of those HtmlUnit goodies - pulling out a Form object from a visited page, setting the fields values and submitting it.. and getting back a Page. So, this is what I've come up with for use in functional tests:
def test_login_logout
page = get :new
form = page.forms.first
form["user[login]"] = "Joe"
form["user[password]"] = "topsecret"
page = form.submit(self)
assert_response :success
page = page.links("@id='signout'").click(self)
assert_response :success
end
Can't say its a replica of HtmlUnit... but it does meet my needs for now. Notice we didn't need to explicitly handle things like session or where the form submits to. It simply goes to where its supposed to go - as rendered by the view. And yes, as you do submit() and click() you might actually cross different controllers. HpricotForms handles that for you.
The main thing I like about this API is that the field names in the form are real. If you're careless like me, and modify your action templates (.rhtml files) but forgot to change both your controller and test, traditionally your test will still pass because you were passing in parameters explicitly, e.g.
post :login, {:user => {:login => "Joe", :password => "topsecret"}}
even though your HTML form fields were changed to "account[login]" and "account[passwd]". But HpricotForms will raise an exception when you try to set values into fields that does not exist in the rendered form.
HpricotForms doesn't add new assert_xxx methods to your test environment since I personally think we've had enough already. It merely deals with navigation. I'm sure programmers out there are capable enough to do their own assertions when they need it.
script/plugin install http://choonkeat.svnrepository.com/svn/rails-plugins/hpricot_forms
Note: It appears that HpricotForms only work on Edge Rails, with simply_restful plugin. This is due to the routing changes. Works with Rails 1.1.4 and Edge Rails. Feedback is welcome.
Update
Added form.extend!(partial) to allow extending the formfields with a separate HTTP request. i.e. if your form appends fields via xmlHttpRequest, you can now say
form = page.forms.first
form.field_names
form["email[0]"] = "email1"
form.extend!(get :on_security_options_clicked) do
form.field_names
form["ssl"] = "true"
end
page = form.submit(self)
Also, to help kick off the writing of code, form.to_code will print out a series of variable assignment satements based on the default values from the form, e.g.
form = page.forms.first
puts form.to_code
choonkeat Wed, 19 Jul 2006 07:26:00 -0500
Source:
http://blog.yanime.org/articles/2006/07/19/hpricotforms To unsubscribe from
this feed, click
here To manage other subscriptions, click
here Powered by
RssFwd Hosting sponsored by
Publicaster - Powerful Email Marketing Solutions by
Blue Sky Factory, Inc