15

我试图为我的Rails 3.2应用程序的Stripe的checkout.js [https://checkout.stripe.com/checkout.js]写一个集成测试。如何在Rails上为Stripe checkout编写集成测试?

当我手动测试时(使用Stripe的测试键),条纹结帐对我来说工作正常,但我无法让Capybara检测并在条纹结帐iframe模式中检测到fill_in电子邮件字段。

我使用骚灵无头的JavaScript,虽然也有水豚,WebKit的甚至同样的问题测试了。

我想要测试的是完整的订阅注册流程,以显示新用户可以在条目中输入付款详细信息后创建订阅者帐户 - 但我无法通过条带结帐弹出窗口。

这里是我的before .. do

describe "show Stripe checkout", :js => true do 
    before do 
    visit pricing_path 
    click_button 'plan-illuminated' 
    stripe_iframe = all('iframe[name=stripe_checkout_app]').last 
    Capybara.within_frame stripe_iframe do   
     fill_in "email", :with => "[email protected]" 
     fill_in "billing-name", :with => "Mr Name" 
     fill_in "billing-street", :with => "test Street" 
     fill_in "billing-zip", :with => 10000 
     fill_in "billing-city", :with => "Berlin" 
     click_button "Payment Info" 
    end 
    end 
    it { should have_selector('button', text: "Subscribe") } 
end 

哪些错误有:

Failure/Error: Capybara.within_frame stripe_iframe do 
Capybara::Poltergeist::TimeoutError: 
    Timed out waiting for response to {"name":"push_frame","args":[null]} 

如果我换了尝试选择正确的iframe(这里建议:Capybara trouble filling in JS modal),像这样:

# stripe_iframe = all('iframe[name=stripe_checkout_app]').last 
# Capybara.within_frame stripe_iframe do 
Capybara.within_frame 'stripe_checkout_app' do 

我还是得到类似的:

Capybara::Poltergeist::TimeoutError: 
    Timed out waiting for response to {"name":"push_frame","args":["stripe_checkout_app"]} 

看来,无论使用哪种javascript测试gem,rspec/capybara都无法找到Stripe checkout iframe。当我检查Selenium时,我看到Choose this Plan按钮被按下并且Checkout弹出,但规格超时寻找电子邮件字段来填写。

任何想法?

我已经尝试过:

  • 选择或找到电子邮件领域的各种方法。
  • 更新所有宝石。
  • 在此之前使用StripeMock(不是它应该涉及,对吗?)。
  • 运行针对条纹自己的网站相同的测试,这给了同样的错误:

测试用:

visit "https://stripe.com/docs/checkout" 
    click_button 'Pay with Card' 
    stripe_iframe = all('iframe[name=stripe_checkout_app]').last 
    Capybara.within_frame stripe_iframe do 
    fill_in 'Email', with: '[email protected]' 
    sleep 3 
    end 

根据我使用哪种方法来选择我收到同样的错误的iframe。只需使用Capybara.within_frame 'stripe_checkout_app' do

Failure/Error: Capybara.within_frame stripe_iframe do 
Capybara::Poltergeist::TimeoutError: 
    Timed out waiting for response to {"name":"push_frame","args":[null]} 

或使用Selenium与stripe_iframe = all('iframe[name=stripe_checkout_app]').last

Failure/Error: Unable to find matching line from backtrace 
SystemStackError: 
    stack level too deep 

甚至只是:

Failure/Error: fill_in 'Email', with: '[email protected]' 
Capybara::ElementNotFound: 
    cannot fill in, no text field, text area or password field with id, name, or label 'Email' found 

...这取决于测试我使用JavaScript的宝石。

非常感谢任何帮助或智慧!

回答

9

我不能得到任何的解决方案,到这里为止的工作对我来说,再阅读这篇文章:https://gist.github.com/nruth/b2500074749e9f56e0b7我意识到,关键是在测试中添加一个延迟,让Stripe有足够的时间来加载结帐窗口和2)处理令牌。

出于这个原因,我能得到工作的唯一代码是这样的(随时与定时播放):

describe "test stripe" do, js: true, driver: :selenium do 

    before do 
    ... # fill in order form or whatever 
    click_button "checkout_with_stripe" 
    sleep(2) # allows stripe_checkout_app frame to load 
    stripe_iframe = all('iframe[name=stripe_checkout_app]').last 
    Capybara.within_frame stripe_iframe do 
     page.execute_script(%Q{ $('input#email').val('[email protected]'); }) 
     page.execute_script(%Q{ $('input#card_number').val('4242424242424242'); }) 
     page.execute_script(%Q{ $('input#cc-exp').val('08/44'); }) 
     page.execute_script(%Q{ $('input#cc-csc').val('999'); }) 
     page.execute_script(%Q{ $('#submitButton').click(); }) 
     sleep(3) # allows stripe_checkout_app to submit 
    end 
    end 

    it "should successfully process the request" do 
    ... # test should pass 
    end 
end 

对于水豚,WebKit的,该sleep诡计没有奏效,也没有悲伤地做@瑞恩的解决方案,我厌倦了试图弄清楚这一点,所以我只是停下脚步,但希望别人会得到它,因为我宁愿使用webkit出于速度原因! (我用的是capybara-webkit 1.3.0

万一有帮助,这里有我的相关版本:

selenium-webdriver 2.35.1 
rspec-rails 2.14.2 
capybara 2.1.0 
stripe 1.16.0 da216fd 
rails 4.1.1 
ruby 2.1.2 
+0

这工作完美,但我确实增加了一点睡眠,而不是把代码放在前一个块,我把它放到实际的场景中。无论哪种方式,很好的解决方案谢谢。 –

+0

'Capybara.default_wait_time = 2'优先于睡眠(2)' –

+0

对我来说唯一的工作解决方案。很遗憾我需要硒来进行这项测试! – hcarreras

5

问题解决!

随着通过他类似的问题,从parov一些帮助&回答[Poltergeist Stripe checkout.js]我跟踪这个问题到使用的是旧版本的水豚“〜> 1.1.2”和随后的依赖,实际上,这对中各种JavaScript测试宝石(即硒,水豚,webkit,poltergeist ...)。

将水豚的bundle update设置为2.3.0,因此将selenium-webdriver设置为2.42.0,将1.1.0的seybat-webdriver设置为1.5.1,即可获得(几乎)所有功能。

硒,通过Capybara trouble filling in JS modal这种方法确实工作:

stripe_iframe = all('iframe[name=stripe_checkout_app]').last 
    Capybara.within_frame stripe_iframe do 
    fill_in "email", with: "[email protected]" 
    ... 
    end 

然而,这并不在骚灵或水豚,WebKit的工作。

对于骚灵,parov的建议工作:

stripe = page.driver.window_handles.last 
    page.within_window stripe do 
    fill_in "email", with: "[email protected]" 
    ... 
    end 

对于水豚,WebKit的我是不是能够得到任何工作,但给我的东西用骚灵我并没有投入太多工作花费大量时间寻找水豚-webkit解决方案。

评论?

+0

硒版本非常感谢,但poltergeist版本不工作,它实际上在那里。 – Filippos

+0

是的,我的工作也停止了?最近的宝石更新。需要再看一遍...... grrr。 –

+1

这似乎不适用于最近的宝石版本(我也使用Poltergeist),它无法找到“卡号”。任何更新? – tirdadc

2

对于水豚,WebKit的,我能得到这个工作:

stripe_iframe = page.driver.window_handles.last 
    page.within_window stripe_iframe do 
    fill_in "email", with: "[email protected]" 
    ... 
    end 
+0

谢谢瑞恩。这与我的poltergeist代码是一样的,所以我会再试一次。总的来说,我发现poljegeist比capybara-webkit更好 - 尽管现在有宝石和所有它们的依赖关系......! –

3

我一直是这样争取一些时间(如要点詹姆斯提到所示),最后发现它太脆弱,太慢而无法测试结帐js。

相反,你可以使用下面的(红宝石,水豚,硒)存根checkout.js和具有条状令牌发表您的形式:

# optionally ensure the iframe was opened 
    expect(page).to have_css('iframe[name="stripe_checkout_app"]') 
    # post the form 
    token = Stripe::Token.create(
    :card => { 
     :number => "4242424242424242", 
     :exp_month => 7, 
     :exp_year => 2019, 
     :cvc => "314", 
     address_line1: Faker::Address.street_address, 
     address_city: Faker::Address.city, 
     address_zip: Faker::Address.postcode, 
     address_country: 'United Kingdom' 
    }, 
) 
    page.execute_script("$('#payment_token').val('#{token.id}');") 
    page.execute_script("$('#our-stripe-payment-form').submit();") 

注:这假定你已经在你的测试环境中加载了stripe api gem(通过你的rails应用程序)并且有一个已注册的API密钥等,否则see the docs

+0

谢谢nruth,我必须试一试。 –

相关问题