Ruby / Rails

[System spec]form_withに変更した時のエラーの対処法

2019年9月28日

こんにちは、Nanayakuです。

form_forからform_withに変更した時、System spec(fill_in)でエラーが起きたので、その対処法を紹介します。

fill_inでエラーになる

どのようなエラーが起きていたかと言うと、fill_inで入力するメールアドレス (label)が見つからないと言うエラーでした。

下記のようなログインのテストを実行します。

RSpec.feature 'Users', type: :system do
 before do
    @user = User.create(
      name: 'TEST_USER',
      email: 'test@example.com',
      password: 'password1234'
    )
 end
 it 'ログインする' do
    visit root_path
    visit login_path
    fill_in 'メールアドレス', with: 'test@example.com'
    fill_in 'パスワード', with: 'password1234'
    click_on 'ログインする'
    expect(page).to have_content 'ログインしました'
 end
end

root_path

login_path

<h1 class="text-conteiner text-center  text-white">ログイン</h1>
<%= form_for :session, url: login_path do |f| %>
 <%= f.label :email, 'メールアドレス' , class: 'text-white' %>
 <%= f.text_field :email, class: 'form-control' %>

 <%= f.label :password, 'パスワード' , class: 'text-white' %>
 <%= f.password_field :password, class: 'form-control' %>

 <%= f.submit "ログインする", class: 'btn-block btn-white vertical-btn' %>
<% end %>

すると、下の画像のようにメールアドレスが見つけられないとエラーが出ます。

'メールアドレス'を'email'に変更しても同じでした。

 

対処法

対処法は、入力部分をidで指定する方法です。

メールアドレス の入力部分に「id: 'sesstion_email'」、パスワードの入力部分に「id: 'sesstion_password'」を追記します。

追記したものが、下記になります。

<h1 class="text-conteiner text-center  text-white">ログイン</h1>
<%= form_with scope: :session, url: login_path, local: true do |form| %>
 <%= form.label :email, 'メールアドレス' , class: 'text-white' %>
 <%= form.text_field :email, class: 'form-control', id: 'sesstion_email' %>
                                #↑↑↑↑↑↑↑↑↑↑↑   
 <%= form.label :password, 'パスワード' , class: 'text-white' %>
 <%= form.password_field :password, class: 'form-control', id: 'sesstion_password' %>
                                    #↑↑↑↑↑↑↑↑↑↑↑↑↑
 <%= form.submit "ログインする", class: 'btn-block btn-white vertical-btn' %>
<% end %>

 

テストは以下のように書き直すと、テストが通ります。

require 'rails_helper'

RSpec.feature 'Users', type: :feature do
  before do
    @user = User.create(
      name: 'TEST_USER',
      email: 'test@example.com',
      password: 'password1234'
    )
  end
  it 'ログインする' do
    visit root_path
    visit login_path
    fill_in 'sesstion_email', with: 'test@example.com'
    fill_in 'sesstion_password', with: 'password1234'
    click_on 'ログインする'
    expect(page).to have_selector '.alert', text: 'ログインしました'
  end
end

 

上手くいかなかった方法

Capybara で同名の CSS セレクタを持つ複数の HTML 要素から任意の要素を見つける | EasyRamble」を参考に、共通のCSSクラスを指定する方法を行いましたが、ログインに成功できませんでした。

自分は、共通のクラスの「form-control」を指定しました。

require 'rails_helper'

RSpec.feature 'Users', type: :system do
  before do
    @user = User.create(
      name: 'TEST_USER',
      email: 'test@example.com',
      password: 'password1234'
    )
  end
  it 'ログインする' do
    visit root_path
    visit login_path
    first(".text-white", visible: false).set("test@example.com")
    page.all(".text-white", visible: false)[1].set("password1234")
    click_on 'ログインする'
    expect(page).to have_selector '.alert', text: 'ログインしました'
  end
end

 

参考サイト

【RSpec/capybara】fill_inが上手く動作しない - Qiita

Capybara で同名の CSS セレクタを持つ複数の HTML 要素から任意の要素を見つける | EasyRamble

 

まとめ

form_forからform_withに変更し、System specの「fill_in」でエラーが起きた時は、「label」名ではなく「id」名で指定する。

-Ruby / Rails
-

© 2021 Nanayaku blog Powered by AFFINGER5