かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

RSpec Capybara name / id のない input の fill_in にハマる

プロダクトの施策であるフォームを react component に置き換えた所、元々あった feature spec で fill_in していた部分が Capybara::ElementNotFound: で落ちるようになってしまいました。

fill_in は id か name が無いと選択できない?

新しくした React component の JS でフォーム送信をしていたので、フォーム内の input タグに id / name 属性が無かったので、feature spec を次のような感じに置き換えていました。

fill_in 'input[type="email"]', with: user.email

=> これはエラーになる。Capybara::ElementNotFound: Unable to find field "input[type=\"email\"]" that is not disabled within #<Capybara::Node::Element tag="div" path="/HTML/BODY[1]/DIV[9]/DIV[1]">

#fill_in([locator], with: , **options) ⇒ Capybara::Node::Element
Locate a text field or text area and fill it in with the given text. The field can be found via its name, id, test_id attribute, placeholder, or label text. If no locator is provided this will operate on self or a descendant.
cf. https://rubydoc.info/github/jnicklas/capybara/master/Capybara%2FNode%2FActions:fill_in

ドキュメントを見た感じ name, id, test_id, attribute, placeholder, label で見つけることはできるようです。
つまりCSSセレクタ的な input[type="email"].inputField みたいなのはダメって事のようです。(単一なものとして取得しづらいからでしょうか…?)

id / name の無い input を Capybara で操作するには findset を使う

今回は fill_in で取得できる id や 属性 が無く、React component は色々な所で使いまわしていたのでテストのために属性を追加したくはないという感じでした。
このような場合は find で要素を見つけてきて set で値をセットすれば OKトノコト。

find('input[type="email"]').set(user.email)

先程のテストをこのように書き換えたら無事テストが実行できるようになりました。₍ᐢ •̥ ̫ • ᐢ₎👌 やったね!  

docker-compose 上で動いてるアプリの RSpec 回そうとしたら TimeoutError になって辛い… (怒りの WIP commit でCIぶん回しました…)


[参考]

カピバラ

カピバラ

  • 作者:渡辺克仁
  • 出版社/メーカー: 東京書籍
  • 発売日: 2015/09/04
  • メディア: Kindle