不能用capybara提交表格,GET而不是POST

时间:2014-06-22 21:41:15

标签: ruby-on-rails forms capybara

我遇到了一个非常奇怪的问题。我正在为我的Rails 3.2.18应用程序编写一些规范,我发现我的表单没有提交,所有的测试都失败了。

我正在使用

  • Rails 3.2.18
  • Rspec 2.13.0
  • Capybara 2.3.0
  • Poltergeist 1.5.1

这是我的登录表单的一个(剥离)示例:

<%= simple_form_for(resource, as: resource_name, url: session_path(resource_name), html: { id: 'new_user_session' }) do |f| %>
  <%= hidden_field_tag :redirect_to, URI(params[:redirect_to] || request.referer || request.env['PATH_INFO']).path %>
  <%= f.input :email %>
  <%= f.input :password %>
  <%= f.input :remember_me, as: :hidden, input_html: { value: 1 } %>
  <%= f.submit t('sign_in') %>
<% end %>

这是功能规范:

require 'spec_helper'

feature 'Sign in' do

  before do
    @user = create(:user, email: 'user@example.com', password: 'supersecret', password_confirmation: 'supersecret')
    @user.confirm!
  end

  scenario 'a registered user' do
    visit '/home'

    expect(page).to     have_content I18n.t('sign_in')
    expect(page).not_to have_content I18n.t('profile')

    click_link I18n.t('sign_in')

    expect(current_path).to eq('/users/sign_in')

    expect(find('#redirect_to').value).to eq('/home')

    within '#new_user_session' do
      fill_in 'user_email',    with: 'user@example.com'
      fill_in 'user_password', with: 'supersecret'

      click_button I18n.t('sign_in')
    end

    expect(current_path).to eq('/home')

    expect(page).to have_content(I18n.t('devise.sessions.signed_in'))

    expect(page).not_to have_content I18n.t('sign_in')
    expect(page).to     have_content I18n.t('profile')
  end

end

测试失败,因为在显然填写表单并单击按钮后,current_path不是预期的那个(我应该被重定向到主页)。

在日志中我可以看到表单未提交POST请求但是有GET(这是初次访问登录页面后的第二个):

Completed 200 OK in 164.1ms (Views: 161.7ms | ActiveRecord: 0.0ms)
Started GET "/users/sign_in" for 127.0.0.1 at 2014-06-22 23:25:23 +0200
Processing by Users::SessionsController#new as HTML

有趣的是,如果我从呈现的页面复制并粘贴HTML代码并将其放在部分而不是simple_form帮助程序中,它就能正常工作,并且测试会通过正确的POST请求传递!我也使用了form_for和form_tag,它也不起作用。这是生成的代码:

<form accept-charset="UTF-8" action="/users/sign_in" class="simple_form new_user" id="new_user_session" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="authenticity_token" type="hidden" value="f8SGSa4y8l9imeaa9oJtsT0JShPw2NEaYOKfA/9IL0O0=" /></div>
  <input id="redirect_to" name="redirect_to" type="hidden" value="/users/sign_in" />
  <div class="input email optional user_email field_with_hint"><label class="email optional" for="user_email">Email</label><input class="string email optional" id="user_email" maxlength="255" name="user[email]" size="50" type="email" value="" /><span class="hint">Email</span></div>
  <div class="input password optional user_password field_with_hint"><label class="password optional" for="user_password">Password</label><input class="password optional" id="user_password" maxlength="128" name="user[password]" size="50" type="password" /><span class="hint">Password</span></div>
  <div class="input hidden user_remember_me"><input class="hidden" id="user_remember_me" name="user[remember_me]" type="hidden" value="1" /></div>
  <input name="commit" type="submit" value="Login" />
</form>

我可以用不同的方式测试这些功能(注册,重置密码和确认),但我想了解我的代码有什么问题。

编辑:这是来自Rspec的失败消息。我想它没有多大帮助,基本上它在检查时是否失败,如果current_path是redirect_to提供的那个:

F

Failures:

  1) Sign in a registered user
     Failure/Error: expect(current_path).to eq('/home')

       expected: "/home"
            got: "/users/sign_in"

       (compared using ==)
     # ./spec/features/signin_spec.rb:29:in `block (2 levels) in <top (required)>'

Finished in 1.09 seconds
1 example, 1 failure

Failed examples:

rspec ./spec/features/signin_spec.rb:10 # Sign in a registered user

它应该是/ home(设计重定向到params [:redirect_to]),但它是/ users / sign_in,因为表单不是通过POST提交的,但是它是相同路径的GET(所以表单只是重新呈现)。

更新:我通过将gem版本升级到最新版本来解决了这个问题。

  • Rails 3.2.21
  • Rspec 3.1.0
  • Capybara 2.4.4
  • Poltergeist 1.5.1

1 个答案:

答案 0 :(得分:0)

我通过将gem版本升级到最新版本来解决了这个问题。

  • Rails 3.2.21
  • Rspec 3.1.0
  • Capybara 2.4.4
  • Poltergeist 1.5.1

问题解决了,我的规格现在正在通过。