使用Capybara,如何切换到带有“_blank”目标的链接的新窗口?

时间:2011-09-30 14:42:53

标签: ruby-on-rails testing selenium webkit capybara

也许这实际上并不是我遇到的问题,但似乎当我“click_link”一个带有target =“_ blank”的链接时,会话会将焦点保持在当前窗口。

所以我要么能够切换到新窗口,要么忽略_blank属性 - 本质上,我只是想让它实际转到链接指示的页面,这样我才能确保它是正确的页面。

我使用webkit和selenium驱动程序。


我在下面提交了我的调查结果。非常感谢更全面的答案。

此外,这只适用于selenium - 相当于webkit驱动程序(或指出我自己可以发现它的位置)将非常感激。

15 个答案:

答案 0 :(得分:74)

Capybara> = 2.3包含新的窗口管理API。它可以像:

一样使用
new_window = window_opened_by { click_link 'Something' }
within_window new_window do
  # code
end

答案 1 :(得分:54)

此解决方案仅适用于Selenium驱动程序

所有打开的窗口都是Selenium的商店

response.driver.browser.window_handles

这似乎是一个数组。最后一项始终是最近打开的窗口,这意味着您可以执行以下操作切换到它。

在一个街区内:

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

只需重新聚焦当前会话:

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

参考水豚问题页面:https://github.com/jnicklas/capybara/issues/173

有关Selenium窗口切换功能的更多详细信息:http://qastuffs.blogspot.com/2010/10/testing-pop-up-windows-using-selenium.html

答案 2 :(得分:9)

现在与Poltergeist一起working。虽然window_handles仍未实现(您需要一个窗口名称,即通过JavaScript弹出窗口):

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

修改:根据以下评论,Poltergeist现在实施window_handles以来version 1.4.0

答案 3 :(得分:9)

Capybara提供了一些方法来轻松查找和切换窗口:

SimpleJobLauncher

此处有更多详情:Capybara documentation

答案 4 :(得分:8)

我知道这是老帖子,但是它的价值在于水豚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

答案 5 :(得分:7)

现在似乎无法使用capybara-webkit:https://github.com/thoughtbot/capybara-webkit/issues/271

: - (

同时https://github.com/thoughtbot/capybara-webkit/issues/129声称可以使用within_window切换窗口。

同样https://github.com/thoughtbot/capybara-webkit/issues/47表明page.driver.browser.switch_to().window(page.driver.browser.window_handles.last)有效。好吧,关于代码阅读。

https://github.com/thoughtbot/capybara-webkit/blob/master/lib/capybara/webkit/browser.rb处的代码至少有一些引用,表明适用于webdriver / firefox的API也适用于webkit。

答案 6 :(得分:6)

现在为capybara-webkit http://github.com/thoughtbot/capybara-webkit/pull/314实施了within_window,在这里你可以看到如何使用它http://github.com/mhoran/capybara-webkit-demo

答案 7 :(得分:6)

截至2014年5月,以下代码适用于capybara-webkit

 within_window(page.driver.browser.window_handles.last) do
   expect(current_url).to eq('http://www.example.com/')
 end

答案 8 :(得分:4)

这适用于capybara-webkit:

within_window(windows.last) do
  # code here
end

(我正在使用capybara 2.4.1和capybara-webkit 1.3.0)

答案 9 :(得分:4)

您也可以传递窗口的名称网址标题 (但现在它的二元化)

  let(:product) { create :product }

  it 'tests' do
    visit products_path
    click_link(product.id)

    within_window(product_path(product)) do
      expect(page).to have_content(product.title)
    end
  end

您也可以传递 labda proc

within_window(->{ page.title == 'Page title' }) do
  click_button 'Submit'
end

希望它将方法用法扩展到更清楚地理解

答案 10 :(得分:4)

要明确更改窗口,请使用 switch_to_window

  def terms_of_use
    terms_window = window_opened_by do
      click_link(@terms_link)
    end
    switch_to_window(terms_window)
  end

该方法浏览器将在新页面中运行,而不是将所有内容包装在 within_window 块中

答案 11 :(得分:3)

在gmail窗口中打开链接时出现此问题:我修复了这个问题:

Given /^(?:|I )click the "([^"]*)" link in email message$/ do |field|

  # var alllinks = document.getElementsByTagName("a");
  # for (alllinksi=0; alllinksi<alllinks.length; alllinksi++) {
  #   alllinks[alllinksi].removeAttribute("target");
  # }

  page.execute_script('var alllinks = document.getElementsByTagName("a"); for (alllinksi=0; alllinksi<alllinks.length; alllinksi++) { alllinks[alllinksi].removeAttribute("target"); }')

  within(:css, "div.msg") do
    click_link link_text
  end

end

答案 12 :(得分:3)

最好的想法是将水豚更新到最新版本(2.4.1)并使用 windows.last 因为page.driver.browser.window_handles已被弃用。

答案 13 :(得分:0)

主要实现(window_opened_by)对我提出了一个错误:

*** Capybara::WindowError Exception: block passed to #window_opened_by opened 0 windows instead of 1

因此,我通过以下解决方案来解决它:

new_window = open_new_window

within_window new_window do
  visit(click_link 'Something')
end

page.driver.browser.window_handles
# => ["CDwindow-F7EF6D3C12B68D6B6A3DFC69C2790718", "CDwindow-9A026DEC65C3C031AF7D2BA12F28ADC7"]

答案 14 :(得分:0)

我个人喜欢以下方法,因为无论是否启用JS,它都能正常工作。

我的规格:

  it "shows as expected" do
    visit my_path

    # ...test my non-JS stuff in the current tab

    switch_to_new_tab

    # ...test my non-JS stuff in the new tab
    
    # ...keep switching to new tabs as much as necessary
  end 

  # OR

  it "shows as expected", js: true do
    visit my_path

    # ...test my non-JS stuff in the current tab
    # ...also test my JS stuff in the current tab

    switch_to_new_tab

    # ...test my non-JS stuff in the new tab
    # ...also test my JS stuff in the new tab

    # ...keep switching to new tabs as much as necessary
  end 

测试助手:

  def switch_to_new_tab
    current_browser = page.driver.browser

    if js_enabled?
      current_browser.switch_to.window(current_browser.window_handles.last)
    else
      visit current_browser.last_request.fullpath
    end
  end

  def js_enabled?
    Capybara.current_driver == Capybara.javascript_driver
  end