joshsz
joshsz

Reputation: 454

Cucumber+Capybara: Problem with a scenario that redirects the browser outside of my app

Given I have a rails app
And I'm using cucumber
And I'm using capybara
And I have an action that results in a redirect_to "http://some.other.domain.com/some_path"
When I test this action
Then the in-app portion of the test works fine
But I see this error: No route matches "/some_path" with {:method=>:get} (ActionController::RoutingError)

So capybara is properly redirected to "http://some.other.domain.com/some_path" but for some reason it thinks it should handle the path portion of the url inside my app. NOTE capybara has no problem at all with "http://some.other.domain.com/" -- my tests pass if I redirect to a url without a path portion.

Is this a bug?

Upvotes: 14

Views: 5002

Answers (7)

daveharris
daveharris

Reputation: 395

I've found a cool solution for Capybara (which can be adapted into Cucumber).

begin
  click_button 'Accept'
rescue ActionController::RoutingError
  # Capybara doesn't redirect externally, so matches '/cb' but that route doesn't exist
  expect(page.current_url).to eq "https://example.com/cb?param=123"
end

Upvotes: 2

grosser
grosser

Reputation: 15097

Using this little snippet:

external_redirect "https://api.twitter.com/oauth/authenticate?x_auth_access_type=read&oauth_token=TOKEN" do
  click_link "Continue with Twitter"
end

def external_redirect(url)
  yield
rescue ActionController::RoutingError # goes to twitter.com/oauth/authenticate
  current_url.must_equal url
else
  raise "Missing external redirect"
end

Upvotes: 1

iGEL
iGEL

Reputation: 17392

I think I had the same problem as you: I just wanted to confirm, that my code redirects to that given URL with the correct status code, but I don't want to do anything on that URL.

The problem is, that the site returns the redirect as expected, but Rack::Test interprets everything to the application under test, and that URL probably doesn't exist. But we can just catch the error and see what the response looked like. This will probably not work with anything else than capybara's default driver.

begin
  click_button('Pay with Paypal')
rescue ActionController::RoutingError
end

expect(page.status_code).to eq(302)
expect(page.response_headers['Location']).to include('paypal.com/cgi-bin/websrc')

Upvotes: 6

Jay Moorthi
Jay Moorthi

Reputation: 877

Here's an example I wrote up about using capybara-mechanize and VCR to test an external redirect.

http://blog.tddium.com/2011/10/04/testing-external-redirects-vcr-capybara-mechanize/

Upvotes: 3

nruth
nruth

Reputation: 1068

@javascript is a currently working solution, though there's also a mechanize driver in the works, which uses rack-test up to the point where you hit an external request.

It's a bit new and I haven't tried it yet, but am meaning to change my external @javascript tests to using it (tagged with @live or @external or similar) for the speed boost.

Upvotes: 1

paulbjensen
paulbjensen

Reputation: 838

I had a similar situation where I was integrating my app with the company's SSO platform. The way I got around this was to get the site running Selenium via appending the @javascript tag against the scenario.

Upvotes: 0

jnicklas
jnicklas

Reputation: 2225

Which driver are you using? The Rack-Test driver isn't going to allow you to request stuff from other domains. If Capybara is doing this with Selenium or Culerity, it's definitely a bug. If you want to help out in getting it fixed, writing a failing spec would be very appreciated :)

Upvotes: 1

Related Questions