概要
RSpecを用いて結合テストコードを実行していた際"element has zero size"というエラー
にぶつかりました。
パッと見で「クリックした要素のサイズがゼロだからか…」と思い、仮説と検証
を行いました。
もしかしたらFontAwesomeを使っている方には同じ現象が起こるかもしれないので、ここで仮説と検証のプロセスを共有します。
環境
- macOS Catalina 10.15.6
- ruby 2.6.5
- Rails 6.0.3.4
- MySQL : 5.6.47
- Bootstrap : 4.3.1
今回のコード
今回は「ユーザーが投稿したタスク内で、コミットを記録していくアプリ」
のテストをします。
テスト内容は「投稿したコミットを編集する」
です。
require 'rails_helper'
RSpec.describe "コミット編集", type: :system do
before do
@commit = FactoryBot.create(:commit)
# user > task > commit の順にネスト
end
context 'コミット編集ができるとき' do
it '正しい情報が入力されれば更新される' do
# ログイン (サポートモジュールで実装済み)
sign_in(@commit.task.user)
# マイページのタスクをクリック
find_link(href: "/tasks/#{@commit.task.id}").click
# コミット編集ボタンをクリック
find_link(href: "/tasks/#{@commit.task.id}/commits/#{@commit.id}/edit").click
=> エラー!
end
end
end
テストコードを実行すると、ターミナルに下記のエラー文が表示されました。
- コミット編集 コミット編集ができるとき 正しい情報が入力されれば更新される
Failure/Error: find_link(href: "/tasks/#{@commit.task.id}/commits/#{@commit.id}/edit").click
Selenium::WebDriver::Error::ElementNotInteractableError:
element not interactable: element has zero size
続いて、このエラー文から仮説と検証を行います。
仮説と検証
エラー文から仮説設定
Failure/Error: find_link(href: "/tasks/***/edit).click
=> find_linkのところでエラー
Selenium::WebDriver::Error::ElementNotInteractableError:
element not interactable: element has zero size
=> 「要素のサイズがゼロだよ」
▶【仮説】find_linkで指定したリンクのサイズがゼロだからクリックできなかった?
検証ツールでリンクを確認
Chromeの検証ツールで、ターゲットにしたリンクを確認します。
find_link(href: "/tasks/#{@commit.task.id}/commits/#{@commit.id}/edit").click
で検索しクリックしたリンクは、下記のaタグです。
確かに、a 0x17.27
の「高さゼロの要素」をクリックしようとしていたことがわかります。
高さがゼロでは、幅があろうと存在しない判定になるようですね
。初めて知りました。
状況整理
今クリックをしたいのは、右側の青い編集アイコン
です。
これをfind_link().click
でクリックしようとしましたが、検証ツールで確認したところ、サイズがないaタグなのでクリックできない
という結果になっています。
ちなみにこのaタグ部分がビューファイルでどう記述されているか見てみましょう。
<%# 必要部分を抜粋 %>
<%= link_to edit_task_commit_path(commit.task, commit) do %>
<i class="fas fa-edit"></i>
<% end %>
編集アイコン<i class="fas fa-edit"></i>
が、実際にリンクとして表示されている文字です。
つまり「リンクをクリック」するにはこのアイコンをクリックすれば良さそう
です。
このアイコンですが、実はページ内の他の部分でも使っているので、個別にid属性を付与してクリックしてみましょう
。
コードを変更▶検証
画像のように、クリックしたい要素にid属性(data-linkId属性)を付与
しました。
<%# 必要部分を抜粋 %>
<%= link_to edit_task_commit_path(commit.task, commit) do %>
<i class="fas fa-edit" data-linkId="commit-edit"></i>
<% end %>
するとHTMLは次のように表示されます。
svg要素(アイコン)にdata-linkId
を付与できました。
data-linkId="commit-edit"
の部分です。
これをfindで取得してクリックしてみます。
require 'rails_helper'
RSpec.describe "コミット編集", type: :system do
before do
@commit = FactoryBot.create(:commit)
# user > task > commit の順にネスト
end
context 'コミット編集ができるとき' do
it '正しい情報が入力されれば更新される' do
# ログイン
sign_in(@commit.task.user)
# マイページのタスクをクリック
find_link(href: "/tasks/#{@commit.task.id}").click
# コミット編集ボタンをクリック
- find_link(href: "/tasks/#{@commit.task.id}/commits/#{@commit.id}/edit").click
+ find("svg[data-linkId='commit-edit']").click
end
end
end
この変更により、
クリック前の画面から
クリック後の画面へ遷移できました!
まとめ
- RSpecでのテスト時、サイズがゼロの要素をクリックしようとしていた
- 指定すべきリンクは、
aタグでなくその中のアイコンだった
- アイコン要素にidを付与したことで、find().clickでクリックを実行できた