web-dev-qa-db-fra.com

Avec Capybara, comment passer à la nouvelle fenêtre pour les liens avec les cibles "_blank"?

Ce n'est peut-être pas vraiment le problème que je rencontre, mais il semble que lorsque je clique sur un lien avec target = "_ blank", la session garde le focus sur la fenêtre actuelle.

Donc, je veux soit pouvoir passer à la nouvelle fenêtre, soit ignorer l'attribut _blank - essentiellement, je veux juste qu'il aille réellement à la page indiquée par le lien afin que je puisse m'assurer que c'est la bonne page.

J'utilise les pilotes webkit et Selenium.


J'ai présenté mes conclusions jusqu'ici ci-dessous. Une réponse plus approfondie est très appréciée.

De plus, cela ne fonctionne qu'avec Selenium - l'équivalent pour le pilote webkit (ou indiquant où je pourrais le découvrir moi-même) serait très apprécié.

74
GlyphGryph

Capybara> = 2.3 inclut la nouvelle API de gestion de fenêtres. Il peut être utilisé comme:

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

Cette solution ne fonctionne que pour le pilote Selenium

Toutes les fenêtres ouvertes sont des magasins dans Selenium

response.driver.browser.window_handles

Ce qui semble être un tableau. Le dernier élément est toujours la fenêtre la plus récemment ouverte, ce qui signifie que vous pouvez effectuer les opérations suivantes pour y accéder.

Dans un bloc:

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

Il suffit de se recentrer pour la session en cours:

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

Référencé sur la page des problèmes de capybara: https://github.com/jnicklas/capybara/issues/17

Plus de détails sur les capacités de changement de fenêtre de Selenium: http://qastuffs.blogspot.com/2010/10/testing-pop-up-windows-using-Selenium.html

54
GlyphGryph

C'est maintenant fonctionne avec Poltergeist. Bien que window_handles n'est toujours pas implémenté (vous avez besoin d'un nom de fenêtre, c'est-à-dire via une popup JavaScript):

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

Edit: Par commentaire ci-dessous, Poltergeist implémente maintenant window_handles depuis version 1.4. .

10

Capybara fournit quelques méthodes pour faciliter la recherche et le changement de fenêtres:

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

Plus de détails ici: documentation Capybara

9
Aravin

Je sais que c'est un vieux post, mais pour ce que ça vaut dans 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
8
bcar

Il semble que ce ne soit pas possible avec capybara-webkit pour le moment: https://github.com/thoughtbot/capybara-webkit/issues/271

:

En même temps --- (https://github.com/thoughtbot/capybara-webkit/issues/129 prétend qu'il est possible de changer de fenêtre avec within_window.

https://github.com/thoughtbot/capybara-webkit/issues/47 suggère que page.driver.browser.switch_to().window(page.driver.browser.window_handles.last) fonctionne. Ah bien, passons à la lecture du code.

Le code à https://github.com/thoughtbot/capybara-webkit/blob/master/lib/capybara/webkit/browser.rb a au moins quelques références qui suggèrent que l'API qui fonctionne pour webdriver/firefox travaille également pour webkit.

7
user132837

Depuis mai 2014, le code suivant fonctionne sur capybara-webkit

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

Maintenant within_window implémenté pour capybara-webkit http://github.com/thoughtbot/capybara-webkit/pull/314 et ici vous pouvez voir comment l'utiliser http: // github. com/mhoran/capybara-webkit-demo

6
E-Hauler

Vous pouvez également passer un nom, rl ou title de la fenêtre également (mais maintenant son dipricated)

  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

Vous pouvez également passer un labda ou un proc

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

souhaite qu'il étende l'utilisation de la méthode pour mieux comprendre

4
itsnikolay

Cela fonctionne pour moi dans capybara-webkit:

within_window(windows.last) do
  # code here
end

(J'utilise capybara 2.4.1 et capybara-webkit 1.3.0)

4
lavaturtle

Pour modifier explicitement la fenêtre, vous utilisez switch_to_window

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

Un navigateur après cette méthode fonctionnera dans la nouvelle page, au lieu de tout envelopper dans un bloc within_window

4
G. I. Joe

La meilleure idée est de mettre à jour capybara vers la dernière version (2.4.1) et d'utiliser simplement windows.last Car page.driver.browser.window_handles Est déconseillé.

3
Adam Piotrowski

J'ai eu ce problème lors de l'ouverture de liens dans une fenêtre gmail: je l'ai résolu comme ceci:

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
3
complistic

L'implémentation principale (window_opened_by) soulève une erreur pour moi:

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

Donc, je le résous par cette solution:

new_window = open_new_window

within_window new_window do
  visit(click_link 'Something')
end

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