简体   繁体   English

在Rails中调试Cucumber + Capybara + PhantomJS中的jQuery Ajax

[英]Debugging jQuery Ajax in Cucumber + Capybara + PhantomJS in Rails

I'm having a very difficult time wrapping my head around this issue, so any help will be greatly appreciated. 我很难绕过这个问题,所以任何帮助都将不胜感激。

All I want to do is test a simple Ajax-based registration form on my project. 我想要做的就是在我的项目上测试一个简单的基于Ajax的注册表单。 If the form submission is successful, you get redirected to a welcome page. 如果表单提交成功,您将被重定向到欢迎页面。 If it isn't, you get the appropriate validation errors associated with each offending field. 如果不是,则会获得与每个违规字段相关的相应验证错误。

For some odd reason, Capybara isn't following the redirect. 由于一些奇怪的原因,Capybara没有遵循重定向。 The Ajax call is being made and I see a new account registered in the database, but the onSuccess callback is either not being called at all, or the redirect is being ignored. 正在进行Ajax调用,我看到在数据库中注册了一个新帐户,但是根本没有调用onSuccess回调,或者忽略了重定向。

Here is what I'm trying to work with (for the sake of brevity, I have condensed the code): 这是我正在尝试使用的(为了简洁起见,我缩写了代码):

Feature: 特征:

  Feature: Registration
    In order to obtain a new account
    As a prospective customer
    I must submit a valid registration form.

    @javascript
    Scenario: A valid registration attempt
      Given an account registration form
      When I complete the form with valid values
      Then I should be redirected to the welcome screen 

Test: 测试:

Given(/^an account registration form$/) do
  visit("/signup")
  assert current_path == "/signup"
end

When(/^I complete the form with valid values$/) do
  within("#signupForm") do
    fill_in("email",    :with => Faker::Internet.email)
    fill_in("name",     :with => Faker::Name.name)
    fill_in("password", :with => "11111111")

    click_link("signupFormSubmit")
  end
end

Then(/^I should be redirected to the welcome screen$/) do
  assert current_path == "/welcome"
end

JavaScript: JavaScript的:

console.log('I am not yet inside you.')

$.post(url, form.serialize(), function(response) {
  // everything went well
  // let's redirect them to the given page
  window.location.replace(response.redirectUrl)
  console.log('I am inside you and it is good.')
}, function(response) {
  // collect error responses from API
  // apply error hints to associated fields
  console.log('I am inside you and something went wrong.')
})

Alright, so this particular test runs just fine up until we get to the point where we're supposed to redirect the user to the welcome screen. 好吧,所以这个特定的测试运行得很好,直到我们到达我们应该将用户重定向到欢迎屏幕的程度。 I have tried everything I possibly can to see what's going on inside the onSuccess , onFailure callbacks, but to no avail. 我已尽力尝试查看onSuccessonFailure回调中发生了什么,但无济于事。 It's like the code isn't even being executed. 这就像代码甚至没有被执行。

I just get the following output from the test run: 我只是从测试运行中得到以下输出:

Then I should be redirected to the welcome screen # features/step_definitions/registration.rb:51
  Failed assertion, no message given. (MiniTest::Assertion)
  ./features/step_definitions/registration.rb:52:in `/^I should be redirected to the welcome screen$/'
  features/registration.feature:15:in `Then I should be redirected to the welcome screen'

It doesn't matter if I raise an exception, it doesn't get picked up. 如果我提出异常并不重要,它就不会被提起。 Neither do the calls to console.log() within the callbacks. 在回调中也没有调用console.log()

Has anyone seen this? 有没有人见过这个? If so, is there a workaround? 如果是这样,有解决方法吗? If you need more information, please just ask, I'll be more than happy to provide. 如果您需要更多信息,请问,我将非常乐意提供。

According to the robots at Thoughtbot and the people at Coderwall, you can do this with a helper method, put into spec/support . Thoughtbot机器人和Coderwall的人们说,你可以用辅助方法做到这一点,投入spec/support They named their module WaitForAjax : 他们将模块命名为WaitForAjax

# spec/support/wait_for_ajax.rb
module WaitForAjax
  def wait_for_ajax
    Timeout.timeout(Capybara.default_wait_time) do
      loop until finished_all_ajax_requests?
    end
  end

  def finished_all_ajax_requests?
    page.evaluate_script('jQuery.active').zero?
  end
end

from there, you just need to load it into your test framework; 从那里,你只需要将它加载到你的测试框架中; for Rspec, that can be done either in the spec/config file or by simply tacking a bit of code to the end of the module file: 对于Rspec,可以在spec / config文件中完成,也可以通过简单地将一些代码添加到模块文件的末尾:

RSpec.configure do |config|
  config.include WaitForAjax, type: :feature
end

Make sure to require spec/support/**/*.rb in your config file, but you probably should do this anyway. 确保在配置文件中需要spec/support/**/*.rb ,但无论如何你可能都应该这样做。

http://www.elabs.se/blog/53-why-wait_until-was-removed-from-capybara http://www.elabs.se/blog/53-why-wait_until-was-removed-from-capybara

Of course, according to the above blog post, this may or may not be needed at all, depending how you structured your page, if you just look for a selector that's unique to your welcome page. 当然,根据上面的博客文章,根据您构建页面的方式,如果您只是寻找欢迎页面独有的选择器,这可能会或可能根本不需要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM