【Rails/RSpec】element has zero size エラーへの対処法

# 概要
RSpecを用いて結合テストコードを実行していた際``"element has zero size"というエラー``にぶつかりました。
パッと見で``「クリックした要素のサイズがゼロだからか…」と思い、仮説と検証``を行いました。

もしかしたらFontAwesomeを使っている方には同じ現象が起こるかもしれないので、ここで仮説と検証のプロセスを共有します。

<br>

# 環境

* macOS Catalina 10.15.6
* ruby 2.6.5
* Rails 6.0.3.4
* MySQL : 5.6.47
* Bootstrap : 4.3.1


<br>

# 今回のコード
今回は``「ユーザーが投稿したタスク内で、コミットを記録していくアプリ」``のテストをします。
``テスト内容は「投稿したコミットを編集する」``です。

```app/spec/system/commits_spec.rb
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
```

テストコードを実行すると、ターミナルに下記のエラー文が表示されました。

> 1) コミット編集 コミット編集ができるとき 正しい情報が入力されれば更新される
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

続いて、このエラー文から仮説と検証を行います。

<br>

# 仮説と検証

## エラー文から仮説設定
> Failure/Error: find_link(href: "/tasks/***/edit).click
=> find_linkのところでエラー

> Selenium::WebDriver::Error::ElementNotInteractableError:
element not interactable: element has zero size
=> 「要素のサイズがゼロだよ」


▶【仮説】find_linkで指定したリンクのサイズがゼロだからクリックできなかった？

<br>

## 検証ツールでリンクを確認

Chromeの検証ツールで、ターゲットにしたリンクを確認します。

``find_link(href: "/tasks/#{@commit.task.id}/commits/#{@commit.id}/edit").click``で検索しクリックしたリンクは、下記のaタグです。

![demo](https://gyazo.com/1caf212380db57eb0e05f1bd71d110b9/raw)

確かに、``a 0x17.27``の「高さゼロの要素」をクリックしようとしていたことがわかります。

``高さがゼロでは、幅があろうと存在しない判定になるようですね``。初めて知りました。

<br>

### 状況整理
``今クリックをしたいのは、右側の青い編集アイコン``です。

これを``find_link().click``でクリックしようとしましたが、検証ツールで確認したところ、``サイズがないaタグなのでクリックできない``という結果になっています。

ちなみにこのaタグ部分がビューファイルでどう記述されているか見てみましょう。

```erb:app/views/commits/_commit.html.erb
<%# 必要部分を抜粋 %>
<%= link_to edit_task_commit_path(commit.task, commit) do %>
  <i class="fas fa-edit"></i>
<% end %>
```

編集アイコン``<i class="fas fa-edit"></i>``が、実際にリンクとして表示されている文字です。

つまり``「リンクをクリック」するにはこのアイコンをクリックすれば良さそう``です。

``このアイコンですが、実はページ内の他の部分でも使っているので、個別にid属性を付与してクリックしてみましょう``。

<br>

## コードを変更▶検証

画像のように、``クリックしたい要素にid属性(data-linkId属性)を付与``しました。

```erb:app/views/commits/_commit.html.erb
<%# 必要部分を抜粋 %>
<%= link_to edit_task_commit_path(commit.task, commit) do %>
  <i class="fas fa-edit" data-linkId="commit-edit"></i>
<% end %>
```

するとHTMLは次のように表示されます。

![demo](https://gyazo.com/1fc63bda662cf3db6a80dce03828c88b/raw)

``svg要素(アイコン)にdata-linkId``を付与できました。
``data-linkId="commit-edit"``の部分です。

これをfindで取得してクリックしてみます。

```app/spec/system/commits_spec.rb
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
```

この変更により、

![demo](https://gyazo.com/8233b9aacd8484a4df5e53f2acade7d1/raw)

クリック前の画面から

![demo](https://gyazo.com/df55ad9f151c7db1061382987b75e900/raw)

クリック後の画面へ遷移できました！

<br>

# まとめ
* RSpecでのテスト時、サイズがゼロの要素をクリックしようとしていた
* 指定すべきリンクは、``aタグでなくその中のアイコンだった``
* アイコン要素にidを付与したことで、find().clickでクリックを実行できた