Functional testing unobtrusive JavaScript to update a portion of a page

I recently updated an application to Rails 3.0, and I ran into a testing
question while doing so. I had one bit of a view that looked like this
with
Rails 2.x:

<% form_remote_tag :url => { :action => :answer, :item => ask },
:update =>
“answer” %>

where the corresponding controller method ended with:

render :partial => 'answer', :object => @item

In the Rails 3 version, :update isn’t available in form_tag, so the
controller method had the render line removed, and instead I added a
file
answer.js.erb containing the following:

$(‘answer’).update("<%= escape_javascript(render :partial => ‘answer’,
:object => @item) %>");

That works great (and I like the HTML that results, much more stylish
than
the older version), but I can’t test it as well as I would have liked.
Before, I could get at the HTML that was generated by that render
:partial
line by using assert_select, as follows:

def test_get_answer
get :index
post :answer, :item => @one.id

assert_select "p.qa", "Answer 1"

end

The problem with the new version is that the return value is now
JavaScript,
which I can’t take apart via assert_select. So, for now, I’m doing
this:

def test_get_answer
get :index
post :answer, :format => ‘js’, :item => @one.id

assert(response.body.include? "Answer 1")

end

which is certainly better than nothing, but isn’t nearly as precise as
I’d
like.

Any recommendations for a better way to test this sort of thing?

Thanks,
David C.
[email protected]

On Wed, Jul 13, 2011 at 9:00 PM, David C. [email protected]
wrote:

Any recommendations for a better way to test this sort of thing?

(Where “this sort of thing” is updating body elements via unobtrusive
JavaScript.)

In case anybody else is curious, here’s what I ended up with:

The source .js.erb file:

$(‘answer’).update(“<%= escape_javascript(render :partial => ‘answer’,
:object => @item) %>”);

The source partial .html.erb file:

(something that includes

text_that_I_want_to_assert_on

)

And the test:

def unescape_javascript(escaped)
escaped.gsub(“\'”, “'”).gsub(“\"”, “"”).gsub(“\n”, “\n”).
gsub(“\\”, “\”).gsub(“<\/”, “</”)
end

def assert_encoded_update(body, element_to_update)
assert_not_nil(/$('(.)').update("(.)");/ =~ body)
assert_equal(element_to_update, $1)
yield(HTML::Document.new(unescape_javascript($2)).root)
end

def test_get_answer
get :index
post :answer, :format => ‘js’, :item => @one.id

assert_encoded_update(response.body, "answer") do |replacement|
  assert_select(replacement, "p.qa", 

“text_that_I_want_to_assert_on”)
end
end

Probably room for improvement (I certainly don’t claim that
unescape_javascript handles all the cases that escape_javascript
handles),
but it works for my purposes.


David C.
[email protected]