With Capybara, how do I switch to the new window for links with "_blank" targets?
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
Related videos on Youtube
GlyphGryph
Updated on July 05, 2022Comments
-
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 almost 12 yearsThis is great, but the second example is a bit misleading. There is no difference between
session
andpage
, sosession.driver.browser
andpage.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 over 10 years@glyphgryph boy I love when solutions just work with a copy & paste, sans all the extra waste.
-
Tony - Currentuser.io about 10 yearsIt's not only for Selenium:
within_window(page.driver.window_handles.last)
works for me with capybara-webkit. -
Tony - Currentuser.io about 10 yearsSee my comment on accepted answer:
within_window(page.driver.window_handles.last)
works for me with capybara-webkit. -
thom_nic over 9 yearsI 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 over 9 yearsAs mentioned below, Capybara has a new syntax for dealing with windows: github.com/jnicklas/capybara#working-with-windows
-
Dave Schweisguth about 9 yearspoltergeist 1.6 implements this API, so at this writing this is the way to go with poltergeist.
-
Dave Schweisguth about 9 yearsCapybara 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 over 8 yearsThis method is deprecated in capybara
DEPRECATION WARNING: Passing string argument to #within_window is deprecated.
-
David over 8 yearsBTW, 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 about 8 years
page.driver.brower.window_handles.las
is now deprecated. Usewindows.last
. See github.com/thoughtbot/capybara-webkit/issues/650