Within a rails app, I have an image (image_submit_tag) on a page that, when selected, sends an ajax request to server. The server receives the request, Does The Right Thing and responds with correct javascript. The correct javascript replaces one image with another. All of this works outside of cucumber/capybara/webkit environment. In other words, for humans.
When I exercise same as a single test (feature) of a rails(3.2.9) app under cucumber(1.3.9)/capybara (2.1.0) using webkit (capybara-webkit 1.0.0) tagged with @javascript I see different results.
Within test env, the response javascript is not getting evaluated by webkit. Instead, within a subsequent step that attempts to find new icon on the page, when I dump page.html all that is reported is the javascript response. That is, the page contains only the returned javascript.
Here is the step that is supposed to be able to see new content (It differs from above description because I have simplified response javascript in attempt to eliminate possibility of js errors).
Then(/^the "(.*?)" icon should be displayed$/) do |icon|
puts "------------------icon display on page------------------"
puts page.html
puts "________________________________________________________"
puts "************* icon displayed response headers ***"
put page.response_headers.inspect
puts "*************************************************"
page.should have_content("some text")
end
I described output of page.html above, but the response headers add to the puzzle. For some reason, webkit (?) thinks there is something wrong with response.
bad URI(is not URI?): {"Content-Type"=>"text/javascript; charset=utf-8",
"X-Ua-Compatible"=>"IE=Edge,chrome=1",
"Etag"=>"\"e7d3ccc2c53dd8e31d6f92d7dbb69dc0\"",
"Cache-Control"=>"max-age=0, private, must-revalidate",
"X-Request-Id"=>"776cf759cc343884091b5daec6a18587",
"X-Runtime"=>"0.048413",
"Server"=>"WEBrick/1.3.1 (Ruby/1.9.3/2013-02-22)",
"Date"=>"Fri, 08 Nov 2013 03:07:43 GMT",
"Content-Length"=>"47", "Connection"=>"Keep-Alive"}
(URI::InvalidURIError)
Finally, here is actual javascript that is returned by rails, Like I said, I have stripped it to bare minimum.
$('#go_on_duty').parent().html("some text");
From looking around for answers, I will anticipate some questions:
1. Yes, I have set Capybara.javascript_driver = :webkit.
2. Yes, the feature is tagged as @javascript
So, does anyone know why the javascript would not be getting evaluated? I have a sneaking suspicion that I am missing something obvious, but my eyes have grown weary.
On a related note, I am only this far because I explicitly set Accept header in request to javascript. I could do this b/c I am using webkit (as below)
page.driver.header 'Accept', 'text/javascript, application/javascript, application/ecmascript, application/x-ecmascript'
Prior to adding above line, my request was arriving at server "as HTML" so I was not even getting partial.js.erb rendered. I am willing to live with above work-around for the time-being but I can't help but think the problems are related either, as in "I am overlooking some simple capybara/rails/cucumber config issue." Again, this is only an issue in test environment; interaction works as expected when human-driven.
Update:
In response to popular demand, here is partial that generates image_submit_tag
<%= form_tag(shifts_start_shift_path, :method => :post , :remote => true) do %>
<%=image_submit_tag("go_on_duty_sign.png", :size=> "35x35",
:id => "go_on_duty",
:title=>"Go On Duty") %>
<% end %>
Here is action code from relevant controller:
def start_shift
@shift = current_staff.current_shift
if !current_staff.on_duty?
@task_assignments = TaskAssignment.where(:shift_id => @shift.id)
respond_to do |format|
format.js
end
end
end
And here is js single line (reproduced from above and, clearly, minimalized ) from start_shift.js.erb template used to render response:
$('#go_on_duty').parent().html("some text");
I hope this helps clear things up, but I would re-emphasize this all works when human-driven. I only see problem under test environment. Thanks...
Environment:
gem 'rails', '3.2.9'
group :test do
gem 'cucumber-rails', '1.4.0'
gem 'rspec-rails', '2.7.0'
gem 'database_cleaner', '0.7.0'
gem 'factory_girl', '2.3.2'
gem 'capybara-webkit', '1.0.0'
end