如何使用 poltergeist 和 Capybara 测试 Stripe.js?
How can I test Stripe.js using poltergeist and Capybara?
我一直在努力为我的用户注册页面编写自动化测试。将通过 Stripe 向用户收取定期订阅费用。他们在同一张表格上输入基本详细信息(电子邮件、密码等)和信用卡详细信息,然后会发生以下流程:
- (在客户端)stripe.js 向 Stripe 的服务器发出 AJAX 请求,其中(假设一切都有效)return 是一个信用卡令牌。
- 我的 javascript 使用信用卡令牌在 HTML 表单中填写隐藏输入,并将表单提交到我的 Rails 服务器。
- (现在在服务器端):我验证用户的基本信息。如果他们无效,return(因为如果他们的电子邮件地址无效,那么通过 Stripe 向他们收费是没有意义的,所以他们无论如何都无法创建帐户。)
- 如果它们有效,尝试创建一个
Stripe::Customer
对象,添加正确的订阅并使用 Stripe 的 ruby gem 等向它们收费
所有这些都工作得很好......除了我不知道如何测试它。测试步骤 #4 非常简单,因为它发生在服务器端,因此我可以使用像 VCR 一样的 gem 模拟 Stripe 调用。
第 1 步给我带来了麻烦。我尝试使用 puffing-billy
和 stripe-ruby-mock
gem 来测试它,但没有任何效果。这是我自己的 javascript(简体):
var stripeResponseHandler = function (status, response) {
console.log("response handler called");
if (response.error) {
// show the errors on the form
} else {
// insert the token into the form so it gets submitted to the server
$("#credit_card_token").val(response.id);
// Now submit the form.
$form.get(0).submit();
}
}
$form.submit(function (event) {
// Disable the submit button to prevent repeated clicks
$submitBtn.prop("disabled", true);
event.preventDefault();
console.log("creating token...");
Stripe.createToken(
// Get the credit card details from the form
// and input them here.
}, stripeResponseHandler);
// Prevent the form from submitting the normal way.
return false;
});
重申一下,当我手动测试时,一切正常。但是我的自动化测试失败了:
Failure/Error: expect{submit_form}.to change{User.count}.by(1)
expected result to have changed by 1, but was changed by 0
当我尝试使用 gem puffing-billy
时,它似乎正在缓存 stripe.js
本身(从位于 js.stripe.com
的 Stripe 自己的服务器加载,未提供来自我自己的应用程序,因为 Stripe 不支持此功能。),但未缓存由 Stripe.createToken
发起的调用。事实上,当我登录我的 Stripe 服务器日志时,似乎甚至没有调用(或者至少 Stripe 没有收到它。)
注意上面我的 JS 中的那些 console.log
语句。当我 运行 我的测试套件时,行 "creating token..." 被打印出来,但 "response handler called." 没有。看起来响应处理程序从未被调用。
我省略了一些细节,因为这个问题已经很长了,但可以根据要求添加更多。我在这里做错了什么?如何测试我的注册页面?
UPDATE 请参阅 stripe-ruby-mock 上的[我对此 Github 问题的评论],了解有关我尝试过和失败的内容的更多信息.
由于超时,我在 Capybara/poltergeist 中进行了手动失败的测试。就我而言,解决方案是等待所有 AJAX 请求完成。 Reference
不确定 Stripe.js 是否在内部使用 JQuery,请尝试检查 stripeResponseHandler
设置的条件。
如果我没理解错的话...
水豚不会知道您的 ajax 请求。您应该能够用 Sinatra 删除 AJAX 请求。拥有它 return 与 VCR 非常相似的固定装置。
这是一篇关于它的文章。
https://robots.thoughtbot.com/using-capybara-to-test-javascript-that-makes-http
您需要在 Capybara 中启动 Sinatra 应用程序,然后匹配 ajax 调用中的 URL。
类似于:
class FakeContinousIntegration < Sinatra::Base
def self.boot
instance = new
Capybara::Server.new(instance).tap { |server| server.boot }
end
get '/some/ajax'
# send ajax back to capybara
end
end
当你启动服务器时,它会return你可以写入你的js可以使用的配置的地址和端口。
@server = App.boot
然后我使用地址和端口来配置 JS 应用程序
def write_js_config
config['api'] = "http://#{@server.host}:#{@server.port}"
config.to_json
end
在 spec_helper.rb
中将配置发送到 js,以便您的脚本指向您的 sinatra 应用程序。我用 gulp 编译。所以我只是在测试之前将配置构建到 is 运行:
system('gulp build --env capybara')
除了提到的 wait_for_ajax
技巧之外,您似乎在更新数据库之前调用 expect
。一种检查方法是在您的代码中添加一个断点 (binding.pry
),并检查它是否是竞争条件问题。
此外,根据 Capybara's documentation,引入对 UI 更改的期望使其 'smartly' 等待 ajax 调用完成:
expect(page).not_to have_content('Enter credit card details')
我一直在努力为我的用户注册页面编写自动化测试。将通过 Stripe 向用户收取定期订阅费用。他们在同一张表格上输入基本详细信息(电子邮件、密码等)和信用卡详细信息,然后会发生以下流程:
- (在客户端)stripe.js 向 Stripe 的服务器发出 AJAX 请求,其中(假设一切都有效)return 是一个信用卡令牌。
- 我的 javascript 使用信用卡令牌在 HTML 表单中填写隐藏输入,并将表单提交到我的 Rails 服务器。
- (现在在服务器端):我验证用户的基本信息。如果他们无效,return(因为如果他们的电子邮件地址无效,那么通过 Stripe 向他们收费是没有意义的,所以他们无论如何都无法创建帐户。)
- 如果它们有效,尝试创建一个
Stripe::Customer
对象,添加正确的订阅并使用 Stripe 的 ruby gem 等向它们收费
所有这些都工作得很好......除了我不知道如何测试它。测试步骤 #4 非常简单,因为它发生在服务器端,因此我可以使用像 VCR 一样的 gem 模拟 Stripe 调用。
第 1 步给我带来了麻烦。我尝试使用 puffing-billy
和 stripe-ruby-mock
gem 来测试它,但没有任何效果。这是我自己的 javascript(简体):
var stripeResponseHandler = function (status, response) {
console.log("response handler called");
if (response.error) {
// show the errors on the form
} else {
// insert the token into the form so it gets submitted to the server
$("#credit_card_token").val(response.id);
// Now submit the form.
$form.get(0).submit();
}
}
$form.submit(function (event) {
// Disable the submit button to prevent repeated clicks
$submitBtn.prop("disabled", true);
event.preventDefault();
console.log("creating token...");
Stripe.createToken(
// Get the credit card details from the form
// and input them here.
}, stripeResponseHandler);
// Prevent the form from submitting the normal way.
return false;
});
重申一下,当我手动测试时,一切正常。但是我的自动化测试失败了:
Failure/Error: expect{submit_form}.to change{User.count}.by(1)
expected result to have changed by 1, but was changed by 0
当我尝试使用 gem puffing-billy
时,它似乎正在缓存 stripe.js
本身(从位于 js.stripe.com
的 Stripe 自己的服务器加载,未提供来自我自己的应用程序,因为 Stripe 不支持此功能。),但未缓存由 Stripe.createToken
发起的调用。事实上,当我登录我的 Stripe 服务器日志时,似乎甚至没有调用(或者至少 Stripe 没有收到它。)
注意上面我的 JS 中的那些 console.log
语句。当我 运行 我的测试套件时,行 "creating token..." 被打印出来,但 "response handler called." 没有。看起来响应处理程序从未被调用。
我省略了一些细节,因为这个问题已经很长了,但可以根据要求添加更多。我在这里做错了什么?如何测试我的注册页面?
UPDATE 请参阅 stripe-ruby-mock 上的[我对此 Github 问题的评论],了解有关我尝试过和失败的内容的更多信息.
由于超时,我在 Capybara/poltergeist 中进行了手动失败的测试。就我而言,解决方案是等待所有 AJAX 请求完成。 Reference
不确定 Stripe.js 是否在内部使用 JQuery,请尝试检查 stripeResponseHandler
设置的条件。
如果我没理解错的话...
水豚不会知道您的 ajax 请求。您应该能够用 Sinatra 删除 AJAX 请求。拥有它 return 与 VCR 非常相似的固定装置。
这是一篇关于它的文章。
https://robots.thoughtbot.com/using-capybara-to-test-javascript-that-makes-http
您需要在 Capybara 中启动 Sinatra 应用程序,然后匹配 ajax 调用中的 URL。
类似于:
class FakeContinousIntegration < Sinatra::Base
def self.boot
instance = new
Capybara::Server.new(instance).tap { |server| server.boot }
end
get '/some/ajax'
# send ajax back to capybara
end
end
当你启动服务器时,它会return你可以写入你的js可以使用的配置的地址和端口。
@server = App.boot
然后我使用地址和端口来配置 JS 应用程序
def write_js_config
config['api'] = "http://#{@server.host}:#{@server.port}"
config.to_json
end
在 spec_helper.rb
中将配置发送到 js,以便您的脚本指向您的 sinatra 应用程序。我用 gulp 编译。所以我只是在测试之前将配置构建到 is 运行:
system('gulp build --env capybara')
除了提到的 wait_for_ajax
技巧之外,您似乎在更新数据库之前调用 expect
。一种检查方法是在您的代码中添加一个断点 (binding.pry
),并检查它是否是竞争条件问题。
此外,根据 Capybara's documentation,引入对 UI 更改的期望使其 'smartly' 等待 ajax 调用完成:
expect(page).not_to have_content('Enter credit card details')