Capybara difficulté à remplir JS modal

permettez-moi de commencer par confirmer qu'il ne s'agit pas d'un double (en ce sens que les réponses qui y sont affichées n'ont pas corrigé mon problème). Ce post est essentiellement mon problème exact: Capybara ne peut pas trouver les champs de formulaire dans le modal de bande pour les remplir.

Voici mon Capybara spec:

describe 'checkout', type: :feature, js: true do
  it 'checks out correctly' do
    visit '/'
    page.should have_content 'Amount: .00'
    page.find('#button-two').click_button 'Pay with Card'
    Capybara.within_frame 'stripe_checkout_app' do
      fill_in 'Email', with: 'example@example.com'
      fill_in 'Name',  with: 'Nick Cox'
      fill_in 'Street', with: '123 Anywhere St.'
      fill_in 'ZIP', with: '98117'
      fill_in 'City', with: 'Seattle'
      click_button 'Payment Info'
      fill_in 'Card number', with: '4242424242424242' #test card number
      fill_in 'MM/YY', with: '02/22'
      fill_in 'CVC', with: '222'
      click_button 'Pay'
    end
    page.should have_content 'Thanks'
  end
end

Le texte de cette spécification est ma plus récente tentative. l'erreur Capybara est Unable to find field "Email".

Ce que j'ai essayé

  • ce tentative la plus récente de remplir le champ par un texte de remplacement comme suggéré ici
  • trouver le champ email par l'attribut name (e.g.,fill_in 'email', with: 'example@example.com')
  • Avec et sans le type: :feature et js: true hachages dans le describe
  • Avec et sans le within_frame appeler Capybara
  • en Essayant de trouver l'entrée par css (par exemple, page.find('.emailInput input').set('example@example.com')
  • Ajouter un within bloc: within('.panel') do autour du formulaire inputs (ne fonctionne pas avec Unable to find css ".panel")
  • Ajouter un sleep 3 avant l'étape précédente dans le cas où il est à la recherche de cette div trop tôt (échoue avec Unable to find css ".panel")
  • Ajouter un appel à find (et page.find) et passer la manipulation de forme comme un bloc (avec et sans within bloc niché dans le find bloc):

Capybara.within_frame 'stripe_checkout_app' do
  page.find('.panel') do
    fill_in 'Email', with: 'example@example.com'
    ...
  end
end

j'ai aussi essayé avec poltergeist.

ce qui est énervant à ce sujet est que j'ai changé le Capybara pilote de lutin de retour pour le sélénium/Firefox et je peux voir physiquement le pilote de l'ouverture de la page, en cliquant sur le bouton et l'éducation de l'modal.

des idées sur la façon D'amener Capybara à interagir avec cette forme?

Modifier

j'ai aussi essayé de coller un binding.pry y, et le débogage avec le levier gem. Le HTML de la page au point que les charges modales est un peu d'éléments, et puis script tags qui insèrent dynamiquement JS dans le à la tête de l'iframe. Voir cette capture d'écran du DOM au point où le binding.pry est frappé (après la fenêtre modale s'ouvre avec la Bande de la forme):

enter image description here

Alors que <div class="emailInput"> est clairement là, mais page.has_selector?('.emailInput') renvoie false dans la console.

Ici est un GitHub essentiel de ce qui se passe quand j'print page.html dans le levier de liaison de la ligne suivante après Capybara.within_frame 'stripe_checkout_app' do. C'est-à-dire, c'est le markup de Capybara perspective, et cela varie énormément du DOM comme montré dans la capture d'écran du DOM de la forme réelle quand il apparaît à l'écran, montré ci-dessus. comme vous pouvez le voir, il n'y a pas d'entrées ou quoi que ce soit avec quoi travailler dans le markup que Capybara voit.

mise à Jour

voici le markup pour la forme qui contient le JS qui exécute le modal. (Le Markup est en haml).

  %form{ action: "/charge?amount=1400", method: 'post', class: 'payment', id: 'fourteen' }
    %article
      %label.amount
        %span Amount: .00

    .stripejs#button-one
      %script{ src: 'https://checkout.stripe.com/checkout.js', class:'stripe-button', :'data-key' => settings.publishable_key, :'data-name' => 'Slow Coffee', :'data-description' => '2 8oz. bags (2/month)', :'data-shipping-address' => true }
17
demandé sur Community 2014-03-12 00:21:27

5 réponses

Je ne peux pas reproduire ce numéro contre page de retrait de la démo de Stripe.

require "capybara"

sess = Capybara::Session.new(:selenium)
sess.visit("https://stripe.com/docs/checkout")
sess.click_button('Pay with Card')
sess.within_frame('stripe_checkout_app') do
  sess.fill_in 'Email', with: 'test@example.com' # it's visible that field becomes filled in
  sleep 3 # just to inspect that manually
end

le problème décrit par vous est parce qu'il y a deux iframes avec nom stripe_checkout_app. within_frame trouve le premier d'entre eux qui ne contient pas de champs de facturation. Pour trouver second iframe vous pouvez faire par exemple:

stripe_iframe = all('iframe[name=stripe_checkout_app]').last
within_frame stripe_iframe do
  # your code here
end
5
répondu Andrei Botalov 2014-03-21 06:11:42

Ne pas avoir de 50 répétitions de commenter, mais, avez-vous essayé d'ajouter un peu de temps sur le capybara de sorte que le modal a le temps de se charger complètement, je suis tombé sur un problème similaire à l'aide de testcafe et de lui donner 2 ou 3 secondes, le temps d'attente a fait le tour.

3
répondu gimiarn1801 2014-03-14 13:34:53

juste jeter une idée ici, depuis que j'ai été coincé sur ces petits problèmes idiosyncratiques et de savoir comment frustrant ils peuvent être....Une fois, J'ai juste essayé D'obtenir Capybara pour cliquer un bouton "Fermer" sur une boîte de dialogue modale Bootstrap Twitter. Il s'avère que pour le faire fonctionner, j'ai dû enfermer le code HTML modal Bootstrap dans une balise "form" et Capybara a pu le trouver. Je me demande si quelque chose comme ça, c'est votre problème?

0
répondu 2014-03-15 21:09:16

Capybara fill_in utilise des ID css et non des classes. Exemple

<input autofocus="autofocus" class="center" id="user_login" name="user[login]" placeholder="Username/Email" type="text" >

Vous pouvez également utiliser <input> au lieu de <div>

0
répondu hunterboerner 2014-03-16 17:50:30

Essayez avec Lutin, à l'aide de la Fenêtre de méthodes de Commutation

https://github.com/jonleighton/poltergeist#window-switching

stripe = page.driver.window_handles.last

page.within_window stripe do
  fill_in "Email", :with => "test@test.com"

  fill_in 'Card number', with: '4242424242424242' #test card number
  fill_in 'MM / YY', with: '02/22'
  fill_in 'CVC', with: '222'

  click_button 'Pay'
end

j'ai trouvé la solution dans ce blog espagnol: numerica latina.

-1
répondu parov 2014-03-21 13:19:46