New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

window.location and current_path/current_url #220

Closed
zekus opened this Issue Dec 27, 2012 · 9 comments

Comments

Projects
None yet
5 participants
@zekus

zekus commented Dec 27, 2012

I have the following scenario to test a drop-down menu that redirects to a new page when an option is selected using javascript window.location

scenario "reload the page selecting the city", :js => true do
  select('London', from: 'search_location')
  current_path.should == '/London'
end

Using the Selenium driver the test passes but when I use Poltergeist, unless I put a sleep 0.1 statement between the select and the current_path test, it refuses to pass.

@jonleighton

This comment has been minimized.

Show comment
Hide comment
@jonleighton

jonleighton Jan 26, 2013

Contributor

I'm not sure what can be done about this from Poltergeist's perspective. We do explicit synchronisation for click, but I don't really want to add it for other stuff (like select) as it will add lots of complexity.

I think the best solution would be for Capybara to support a matcher like:

page.should have_path("/London")

That imaginary matcher would cause Capybara to poll until either the timeout is reached or the path matches.

Maybe you could work on adding that to Capybara?

Contributor

jonleighton commented Jan 26, 2013

I'm not sure what can be done about this from Poltergeist's perspective. We do explicit synchronisation for click, but I don't really want to add it for other stuff (like select) as it will add lots of complexity.

I think the best solution would be for Capybara to support a matcher like:

page.should have_path("/London")

That imaginary matcher would cause Capybara to poll until either the timeout is reached or the path matches.

Maybe you could work on adding that to Capybara?

@zekus

This comment has been minimized.

Show comment
Hide comment
@zekus

zekus Jan 27, 2013

Ok Jon, thanks for the suggestion.I'll try that ;)

zekus commented Jan 27, 2013

Ok Jon, thanks for the suggestion.I'll try that ;)

@hakanensari

This comment has been minimized.

Show comment
Hide comment
@hakanensari

hakanensari Jul 10, 2013

Contributor

@jonleighton not to reopen a can of worms but just to let you know that this is not that a super uncommon problem.

We ran into the same thing while driving eBay's sign-in form, where submitting resorts to window.location under the hood for whatever unfathomable reason. Capybara with Poltergeist remains on the interstitial sign-in page. The Selenium driver, as @zekus found out as well, redirects, making the form behave as expected.

As an aside, we had the same issue with CasperJS (we continually shop around for the best toolkit) so am assuming the behaviour originates in PhantomJS rather than Poltergeist.

For posterity, one of the many possible hacks to make Poltergeist roll on in a less inelegant way than simply sleeping is:

page.document.synchronize do
  raise Capybara::ElementNotFound if current_url.include?('signin') # a phrase that matches the final URL
end

Of course, it would have been great if the page just redirected as expected.

PS: ❤️ Capybara + Poltergeist

Contributor

hakanensari commented Jul 10, 2013

@jonleighton not to reopen a can of worms but just to let you know that this is not that a super uncommon problem.

We ran into the same thing while driving eBay's sign-in form, where submitting resorts to window.location under the hood for whatever unfathomable reason. Capybara with Poltergeist remains on the interstitial sign-in page. The Selenium driver, as @zekus found out as well, redirects, making the form behave as expected.

As an aside, we had the same issue with CasperJS (we continually shop around for the best toolkit) so am assuming the behaviour originates in PhantomJS rather than Poltergeist.

For posterity, one of the many possible hacks to make Poltergeist roll on in a less inelegant way than simply sleeping is:

page.document.synchronize do
  raise Capybara::ElementNotFound if current_url.include?('signin') # a phrase that matches the final URL
end

Of course, it would have been great if the page just redirected as expected.

PS: ❤️ Capybara + Poltergeist

@monsteronfire

This comment has been minimized.

Show comment
Hide comment
@monsteronfire

monsteronfire Jun 19, 2017

@hakanensari That fix helped me. Thank you! :)

monsteronfire commented Jun 19, 2017

@hakanensari That fix helped me. Thank you! :)

@twalpole

This comment has been minimized.

Show comment
Hide comment
@twalpole

twalpole Jun 19, 2017

Contributor

@monsteronfire That answer is from 4 years ago, and completely outdated. Nowadays, just use the have_current_path matcher

expect(page).to have_current_path('whatever path you expect')
Contributor

twalpole commented Jun 19, 2017

@monsteronfire That answer is from 4 years ago, and completely outdated. Nowadays, just use the have_current_path matcher

expect(page).to have_current_path('whatever path you expect')
@monsteronfire

This comment has been minimized.

Show comment
Hide comment
@monsteronfire

monsteronfire Jun 20, 2017

@twalpole Yes, I realised that when I started testing it and found it passes with any phrase at all.

Thanks for your comment, I'll try it out. 👍 🦄

monsteronfire commented Jun 20, 2017

@twalpole Yes, I realised that when I started testing it and found it passes with any phrase at all.

Thanks for your comment, I'll try it out. 👍 🦄

@monsteronfire

This comment has been minimized.

Show comment
Hide comment
@monsteronfire

monsteronfire Jun 20, 2017

@twalpole I don't think that solution works for me, unfortunately. I'm trying to test a redirect that is triggered by setting window.location.href = 'http://external-domain.com' in JS. Thanks, anyway. :)

monsteronfire commented Jun 20, 2017

@twalpole I don't think that solution works for me, unfortunately. I'm trying to test a redirect that is triggered by setting window.location.href = 'http://external-domain.com' in JS. Thanks, anyway. :)

@twalpole

This comment has been minimized.

Show comment
Hide comment
@twalpole

twalpole Jun 20, 2017

Contributor

@monsteronfire Shouldn't make any difference how you're triggering the page change, the have_current_path matcher will wait/retry until the "browser" tells Capybara it's on that page, or Capybara.default_max_wait_time seconds has expired (which will raise an error). The only difference when dealing with an external domain is that you might want to pass the url option so the entire url gets compared - http://www.rubydoc.info/gems/capybara/Capybara/SessionMatchers#has_current_path%3F-instance_method

expect(page).to have_current_path('http://external-domain.com', url: true)
Contributor

twalpole commented Jun 20, 2017

@monsteronfire Shouldn't make any difference how you're triggering the page change, the have_current_path matcher will wait/retry until the "browser" tells Capybara it's on that page, or Capybara.default_max_wait_time seconds has expired (which will raise an error). The only difference when dealing with an external domain is that you might want to pass the url option so the entire url gets compared - http://www.rubydoc.info/gems/capybara/Capybara/SessionMatchers#has_current_path%3F-instance_method

expect(page).to have_current_path('http://external-domain.com', url: true)
@monsteronfire

This comment has been minimized.

Show comment
Hide comment
@monsteronfire

monsteronfire Jun 21, 2017

@twalpole Thank you so much! It worked perfectly after I added url: true.

monsteronfire commented Jun 21, 2017

@twalpole Thank you so much! It worked perfectly after I added url: true.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment