Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make Capybara do a DELETE request in a Cucumber feature?

I am using Cucumber and Capybara. I need to make an HTTP DELETE request. Previously the features used webrat, so a simple statement like

visit "/comment/" + comment_id, :delete

worked, but now I am using Capybara.

The way to do a GET request is simply:

get 'path'

And to do a post request:

page.driver.post 'path'

But how can I simulate a DELETE request?

I found out that the driver Capybara is using is Capybara::RackTest::Driver, if that is any help.

I have also tried:

Capybara.current_session.driver.delete "/comments/" + comment_id

But that does not work.

like image 896
umar Avatar asked Feb 10 '12 13:02

umar


4 Answers

page.driver.submit :delete, "/comments/#{comment_id}", {}

Documentation at: http://rubydoc.info/gems/capybara/1.1.2/Capybara/RackTest/Browser:submit

like image 98
1000 Needles Avatar answered Nov 22 '22 05:11

1000 Needles


In case you are using a driver that doesn't support custom HTTP requests (e.g. Capybara-webkit, see closed issue and current driver), you could just temporary switch to RackTest driver to submit your request.

For example:

# Submit an HTTP delete request, using rack_test driver
def http_delete path
  current_driver = Capybara.current_driver
  Capybara.current_driver = :rack_test
  page.driver.submit :delete, path, {}
  Capybara.current_driver = current_driver
end
like image 28
mrmrf Avatar answered Nov 22 '22 06:11

mrmrf


page.driver.delete("/comments/#{comment_id}")

Use delete works fine. No need to use the lower level submit method for this.

PS: tested with capybara-webkit 1.6.0 and capybara 2.4.4

like image 25
Olivier Lacan Avatar answered Nov 22 '22 05:11

Olivier Lacan


If you need a solution that will retain session information (e.g., if you need your DELETE request to be issued as an authenticated user), and that will work with both the :rack_test driver and the :webkit driver (assuming you have jQuery available in your app), try something like this:

def manual_http_request(method, path)
  if Capybara.current_driver == :rack_test
    page.driver.submit method, path, {}
  else
    page.execute_script("$.ajax({url: '#{path}', data: {}, type: '#{method}'});")
    # Wait for the request to finish executing...
    Timeout.timeout(10) { loop until page.evaluate_script('jQuery.active').zero? }
  end
end

I suspect this will also work with the :selenium driver but have not tested it. Maybe someone else can chime in on that.

like image 23
Chris W. Avatar answered Nov 22 '22 05:11

Chris W.