📝

《初学者向け》RSpecで要素にcssの値が適用されているかチェックしたいんじゃあ...!

2024/08/20に公開

初めに

皆さん、お疲れさマッチョです🦍

私は、昨年4月より某プログラミングスクールにてプログラミング学習を開始し、今年の8月にエンジニアキャリアをスタートする事となったゴリラです。

現在、社内で絶賛活動中の『ブログアウトプットTIME』という場で、アウトプットのための記事を書く時間が用意されています。(ありがたやありがたや....!)


今回は、実務にてRSpec作成中に

「おん?ボタンにpointer-events: noneが適用されとるのかテスト通したいのにエラー発生しちゃうわよぉ!?」

と詰まってしまいましたので、備忘録として記事を書かせていただきました。

ちなみに、Zennでの投稿は初めてですのでお手柔らかにお願いします🙇‍♂️

概要

詳細な内容については伏せますが、ざっくりと概要についてお話ししたいと思います。

  • とある投稿アプリがあり、管理者用投稿一覧画面から投稿を削除することが出来る
  • 投稿削除ボタンをクリックすることで、確認モーダルが開く
  • 確認モーダル内のチェックボックスをクリックすることで、モーダル内の削除ボタンが活性化される
  • モーダル内の削除ボタンをクリックすることで投稿が削除される

と、まぁざっくりこんな感じですね🧐
ここで、下記部分のRSpecを書くときに少々手こずりました...

  • 確認モーダル内のチェックボックスをクリックすることで、モーダル内の削除ボタンが活性化される

厳密には、『チェックボックスがチェックされていない場合は、モーダル内の削除ボタンは非活性状態である』 という内容でテストを書く時に手こずりました。

説明

状況の確認

では、まず実際にコードを交えて状況の説明をしていきたいと思います。

まず、今回非活性化であることをチェックしたいボタン要素・cssは下記の内容です。

<a href="#" class="delete-button" id="muscle-gorilla">
  <%= '削除する' %>
</a>
.delete-button {
  pointer-events: none;
}



そして、JavaScriptを使い、ボタン要素に対してdelete-buttonクラスの追加・削除を行い、ボタンの活性・非活性を管理しています。

実際に起きたエラー

では、ここから実際にRSpecで発生したエラーを交えて説明していきます。

まず、今回のテストの目標としては『モーダル内の削除ボタンが非活性状態であるかチェックする』です。
この内容を細分化すると下記の通りとなります。

  1. 「削除する」テキストを持つaタグ要素を取得
  2. 取得した要素のstyleからpointer-eventsを指定し、値を取得
  3. 取得した値がnoneであるかチェック

これをRSpecに落とし込むと下記の内容となります。

element = find('a', text: '削除する')
pointer_events = element[:style]['pointer-events']
expect(pointer_events).to eq('none')

「よっしゃ完璧や!これでテストして再Pushするでぇ〜!」

と意気揚々としていたのも束の間...下記のエラーが発生してしまいました🙄

Failure/Error: expect(pointer_events).to eq('none')
     
       expected: "none"
            got: nil
     
       (compared using ==)

どうやらpointer_eventsnoneであることを期待しているのに対して、nilを返しているみたいです...

原因と対策

まず、原因について説明していきたいと思います。

原因についてなのですが、pointer_eventsがnilになっているということは、前の処理でちゃんとcssの値を取得できていないことが原因となっています。

なんと...RSpecにおいてはオブジェクトに対してstyleを指定した場合、返すのはインラインスタイルのみとのこと...!

なので、外部スタイルシート(.css.scssなど)で設定されているスタイルを取得したい場合、オブジェクトに対してnativeメソッドを使用してネイティブオブジェクトとして取得する必要があるとのこと😳

ということで、上記の内容を踏まえ修正したRSpecは下記となります。

element = find('a', text: '削除する').native
pointer_events = element.css_value('pointer-events')
expect(pointer_events).to eq('none')
  1. 「削除する」テキストを持つaタグ要素をネイティブオブジェクトとして取得
  2. 取得したネイティブオブジェクトに対してcss_valueを使用し、cssの値を取得
  3. 取得した値がnoneであるかチェック

となります。

単純に、適用されているstyleから欲しいクラスを指定するだけではcss値は取得できないんですねぇ....
嵌められました🦍(冗談です)

最後に

今回は、RSpecにて要素にcssの値が適用されているかチェックするテストの書き方について記事を作成させていただきました!

いやはや、RSpecは奥が深くまだまだ自分の知らない知識が盛り沢山です😆
あと、実務に入ってから感じたこととして「RSpecの書き方って200通りあんねん。」ということ。

厳密に何通りかは分かりませんが...笑
それくらいRSpecの書き方には多種多様な方法が存在するなぁ、と痛感しました。


最後まで拝読いただき、ありがとうございマチョした🦍

HERO Tech Blog

Discussion