所以这是一个使用Docker的非常基本的Rails 5应用程序,它包括我从头开始构建的一些用户身份验证(不使用Devise等)。现在,我想开始学习与Capybara的请求规范,但我正在尝试使用它看起来很奇怪的问题。
这是我的登录表单(public class MyActivity extends Activity {
//boolean field member initialized as false by default
private boolean isLightOn;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_layout_id);
final Button button = findViewById(R.id.button_id);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if(isLightOn){
FlashTask.flash.off();
} else{
FlashTask.flash.on();
}
isLightOn = !isLightOn;
}
});
}
}
):
sessions.new.erb
我的<%= form_tag sessions_path do %>
<form class="m-t" role="form" action="/">
<div class="form-group">
<%= text_field_tag :email, params[:email], class: 'form-control', placeholder: "Email Address", required: "" %>
</div>
<div class="form-group">
<%= password_field_tag(:password, nil, class: 'form-control', placeholder: "Password", required: "") %>
</div>
<div class="form-group">
<%= check_box_tag :remember_me, 1, params[:remember_me] %>
<%= label_tag :remember_me %>
</div>
<div class="actions"><%= submit_tag "Log In", class: "btn btn-primary block full-width m-b" %></div>
</form>
<% end %>
:
requests/sessions_spec.rb
现在,如果你手动测试它会有效,所以我认为Capybara会看到同样的事情。但它一直都失败了。我已经配置了应用程序,因此如果您尝试访问受保护的控制器并且您尚未登录,则会将您重定向到require "rails_helper"
RSpec.feature "Login", :type => :feature do
scenario "handles wrong email and password gracefully" do
visit login_path
fill_in "Email Address", :with => "something"
fill_in "Password", :with => "something"
click_button "Log In"
expect(page).to have_text("Email or password incorrect")
end
end
并闪烁显示/login
的消息。 Rspec测试正在返回,这很奇怪 - 这表明Capybara试图访问另一页。
所以我把测试日志(Please log in to see this page
)
我发现的东西令我感到困惑:
docker-compose run web tail -f log/test.log
第一位没问题,GET Login由SessionsController #new处理。然后,(见第6行)由于某种原因,Capybara试图获取根URL,传递电子邮件/密码参数。我的根URL被映射到LocationsController#index,用户不允许访问,所以使用消息Started GET "/login" for 127.0.0.1 at 2017-10-17 06:59:26 +0000
Processing by SessionsController#new as HTML
Rendering sessions/new.html.erb within layouts/empty
Rendered sessions/new.html.erb within layouts/empty (1.1ms)
Completed 200 OK in 6ms (Views: 6.1ms | ActiveRecord: 0.0ms)
Started GET "/?email=something&password=[FILTERED]&commit=Log+In" for 127.0.0.1 at 2017-10-17 06:59:26 +0000
Started GET "/locations" for 127.0.0.1 at 2017-10-17 06:59:26 +0000
Processing by LocationsController#index as HTML
Redirected to http://www.example.com/login
Filter chain halted as :authenticate rendered or redirected
Completed 302 Found in 2ms (ActiveRecord: 0.0ms)
Started GET "/login" for 127.0.0.1 at 2017-10-17 06:59:26 +0000
Processing by SessionsController#new as HTML
Rendering sessions/new.html.erb within layouts/empty
Rendered sessions/new.html.erb within layouts/empty (1.1ms)
Completed 200 OK in 6ms (Views: 4.9ms | ActiveRecord: 0.0ms)
(0.4ms) ROLLBACK
重定向回/ login。该按钮实际上做的是发送一个POST到SessionsController #create。如果您在手动操作时查看日志,那确实会发生什么:
Please log in to see this page
我无法解决为什么在按下按钮时Capybara会为您手动点击按钮执行完全不同的请求。
非常感谢!
答案 0 :(得分:1)
首先澄清一些。
RSpec.feature
和:type => :feature
:type => :feature
时,您无需指定RSpec.feature
,因为已经设置了form_tag
。现在谈谈你的问题。您在视图代码中嵌套了表单,因为<form>
创建了一个<form>
元素,然后您在其中直接有另一个rack-test
元素(注意:发布实际的HTML总是更好,而不是erb所以人们可以看到实际的HTML是什么)。将其与您似乎使用js: true
驱动程序(没有rack-test
元数据)的事实相结合,当HTML无效时(嵌套表单是这样的),其行为与真实浏览器的行为不同,你最终得到了当前的行为。我猜想当你使用真正的浏览器时,内部表单元素被忽略,外部表单元素的方法属性等于“post”,因此它被发布。使用method
时,它可能会提交没有<form class="m-t" role="form" action="/">
属性的内部表单元素,因此默认为“get”。从视图中删除无关的tf vc scorch
表单元素,应该可以正常工作。