With Capybara, how do I switch to the new window for links with "_blank" targets?

41,557

Solution 1

Capybara >= 2.3 includes the new window management API. It can be used like:

new_window = window_opened_by { click_link 'Something' }
within_window new_window do
  # code
end

Solution 2

This solution only works for the Selenium driver

All open windows are stores in Selenium's

response.driver.browser.window_handles

Which seems to be an array. The last item is always the window that was most recently opened, meaning you can do the following to switch to it.

Within a block:

new_window=page.driver.browser.window_handles.last 
page.within_window new_window do
  #code
end

Simply refocus for current session:

session.driver.browser.switch_to.window(page.driver.browser.window_handles.last)

Referenced on the capybara issues page: https://github.com/jnicklas/capybara/issues/173

More details on Selenium's window switching capabilities: http://qastuffs.blogspot.com/2010/10/testing-pop-up-windows-using-selenium.html

Solution 3

Capybara provides some methods to ease finding and switching windows:

facebook_window = window_opened_by do
  click_button 'Like'
end
within_window facebook_window do
  find('#login_email').set('[email protected]')
  find('#login_password').set('qwerty')
  click_button 'Submit'
end

More details here: Capybara documentation

Solution 4

This is now working with Poltergeist. Although window_handles is still not implemented (you need a window name, i.e. via a JavaScript popup):

within_window 'other_window' do
  current_url.should match /example.com/
end

Edit: Per comment below, Poltergeist now implements window_handles since version 1.4.0.

Solution 5

I know this is old post, but for what its worth in capybara 2.4.4

within_window(switch_to_window(windows.last)) do 
    # in my case assert redirected url from a prior click action
    expect(current_url).to eq(redirect['url'])
end
Share:
41,557

Related videos on Youtube

GlyphGryph
Author by

GlyphGryph

Updated on July 05, 2022

Comments

  • GlyphGryph
    GlyphGryph about 2 years

    Perhaps this isn't actually the issue I'm experiencing, but it seems that when I "click_link" a link with target="_blank", the session keeps the focus on the current window.

    So I either want to be able to switch to the new window, or to ignore the _blank attribute - essentially, I just want it to actually go to the page indicated by the link so I can make sure it's the right page.

    I use the webkit and selenium drivers.


    I submitted my findings thus far below. A more thorough answer is much appreciated.

    Also, this only works with selenium - the equivalent for the webkit driver (or pointing out where I could discover it myself) would be much appreciated.

  • Steve Jorgensen
    Steve Jorgensen almost 12 years
    This is great, but the second example is a bit misleading. There is no difference between session and page, so session.driver.browser and page.driver.browser actually refer to the same thing. That messed me up while trying to adapt this to a different context, accessing Capybara through a different library, and not using the DSL. I had to read the Capybara DSL code to figure out that to access 'page`, I just need to access the session.
  • nfriend21
    nfriend21 over 10 years
    @glyphgryph boy I love when solutions just work with a copy & paste, sans all the extra waste.
  • Tony - Currentuser.io
    Tony - Currentuser.io about 10 years
    It's not only for Selenium: within_window(page.driver.window_handles.last) works for me with capybara-webkit.
  • Tony - Currentuser.io
    Tony - Currentuser.io about 10 years
    See my comment on accepted answer: within_window(page.driver.window_handles.last) works for me with capybara-webkit.
  • thom_nic
    thom_nic over 9 years
    I just tried page.within_window page.driver.browser.window_handles.last do ... and it appears to work as expected in Poltergeist. No need to give a window name. So this answer might need to be updated.
  • Sarah
    Sarah over 9 years
    As mentioned below, Capybara has a new syntax for dealing with windows: github.com/jnicklas/capybara#working-with-windows
  • Dave Schweisguth
    Dave Schweisguth about 9 years
    poltergeist 1.6 implements this API, so at this writing this is the way to go with poltergeist.
  • Dave Schweisguth
    Dave Schweisguth about 9 years
    Capybara 2.3 deprecates calling within_window with a String: DEPRECATION WARNING: Passing string argument to #within_window is deprecated. Pass window object or lambda. The method documented by Andrey Botalov fixes this deprecation.
  • Aravin
    Aravin over 8 years
    This method is deprecated in capybara DEPRECATION WARNING: Passing string argument to #within_window is deprecated.
  • David
    David over 8 years
    BTW, instead of comments you could use heredoc syntax: page.execute_script <<-JS var alllinks = document.getElementsByTagName("a"); for (alllinksi=0; alllinksi<alllinks.length; alllinksi++) { alllinks[alllinksi].removeAttribute("target"); } JS Comments would only allow inline code, so make sure there are line breaks before and after "JS", but you get the idea. this way you don't have to manage code in two places and most editors will highlight them anyway.
  • smcgregor
    smcgregor about 8 years
    page.driver.brower.window_handles.las is now deprecated. Use windows.last. See github.com/thoughtbot/capybara-webkit/issues/650