🎗

RSpecのCapybaraをまとめてみた

2024/01/27に公開

はじめに

RSpecのシステムスペックのひとつであるCapybaraを使うとき、自分用にまとめたメモが見にくかったので改めてまとめることにしました。
それにあたり「せっかくだからZennに投稿してみよう」と初投稿させていただきます。
初学者ゆえ、不備などあるかと思いますがそのときはそっと教えていただけると幸いです。

書き方と内容

アクセス

特定のページへアクセスします。

visit 'パス'
# 例
visit '/users'
visit users_path

現在のパスを確認することで特定のパスへアクセスできているか確認できます。
マッチャーを使い確認していきます。

# /usersにアクセスできているか
expect(page).to have_current_path(users_path)
# /users/1にアクセスできているか
expect(page).to have_current_path(user_path(1))

HTTPステータスコードを使うと「アクセスに成功しているか」「アクセスに失敗しているか」などを確認できます。

visit '/admin'
# アクセスに成功できているか確認するとき
expect(page).to have_http_status(200), 'アクセスに失敗しています。'
# アクセス権限でページにアクセスできないか確認するとき
expect(page).not_to have_http_status(403), 'アクセスに成功しています。'
# ページが見つからないか確認するとき
expect(page).not_to have_http_status(404), 'ページが存在しています。'

リンクやボタンをクリック

以下のHTMLがあったとします。

<a href="url">ただのリンク</a>
<a href="url" id="link-id">idのリンク</a>
<a href="url" class="link-class">classのリンク</a>
<button>ただのボタン</button>
<button id="button-id">idのボタン</button>
<button class="button-class">classのボタン</button>

上記をクリックするには下記のように書きます。

# ただのリンク、と表示されているaタグをクリック
click_link 'ただのリンク'
# link-idというidがついているaタグをクリック
click_link 'link-id'
# link-classというclassがついているaタグをクリック
click_link 'link-class'

# ただのボタン、と表示されているbuttonタグをクリック
click_button 'ただのボタン'
# button-id、というidがついているbuttonタグをクリック
click_button 'button-id'
# button-class、というclassがついているbuttonタグをクリック
click_button 'button-class'

# ただのリンク、と表示されているaタグかbuttonタグをクリック
click_on 'ただのリンク'
# ただのボタン、と表示されているaタグかbuttonタグをクリック
click_on 'ただのボタン'

フォーム操作

下記のようなフォームがあったとします。

<label for="first-name">お名前</label>
<input type="text" id="first-name" />

<input type="radio" id="radio1" name="radio-button" />
<label for="radio1">ラジオボタン1</label>

<input type="radio" id="radio2" name="radio-button" />
<label for="radio2">ラジオボタン2</label>

<input type="radio" id="radio3" name="radio-button" />
<label for="radio3">ラジオボタン3</label>

<input type="checkbox" id="check1" name="check-button" />
<label for="check1">チェックボックス1</label>

<input type="checkbox" id="check2" name="check-button" checked />
<label for="check2">チェックボックス2</label>

<label for="image">画像を添付</label>
<input type="file" id="image" />

<select id="select-box">
  <option>セレクト1</option>
  <option>セレクト2</option>
  <option>セレクト3</option>
</select>

上記を確認するには以下のように書きます。
id、name属性から設定可能ですが、対応するラベルタグがあればラベルからも設定可能です。

# テキストフィールドで「お名前」を入力
fill_in 'お名前', with: 'John'
# ラジオボタンで「ラジオボタン1」を選択
choose 'ラジオボタン1'
# チェックボタンで「チェックボックス1」にチェックを入れる
check 'チェックボックス1'
# チェックボタンで「チェックボックス2」のチェックを外す
uncheck 'チェックボックス2'
# 「画像を添付する」から画像を設定。パスは適宜設定
attach_file '画像を添付', '/path/to/image.jpg'
# セレクトボックスで「セレクト1」を選択
select 'セレクト1', from: 'select-box'

ページ内にあるかどうか

page.has_をつかうとページ内に存在するかどうかを確認できます。
マッチャーを使っても確認可能です

# ページ内にh1タグが存在するかどうか
page.has_selector?('h1')
expect(page).to have_selector('h1')

# ページ内にh1にtitleというクラスがついているか
page.has_css?('h1.title')
expect(page).to have_css('h1.title')

# ページ内に「タイトル」という文字があるか
page.has_content?('タイトル')
expect(page).to have_content('タイトル')

検索

特定のタグを検索します。

# すべてのaタグを検索
all('a')
# 検索したあとに操作も可能
all('a').each {|a| ... }
# button-classというクラスがついたボタンを検索
find_button('.button-class')
# ページ内の要素をidでのみ検索
find_by_id('id-name')
# ページ内のフォームにあるフィールド(今回はidがfirst-nameであるもの)を検索
find_field('#first-name')
# ページ内のaタグ(今回はclassがlink-classであるもの)を検索
find_link('.link-class')

スコープ

「特定の要素内でのみ検索したい」などのときはスコープが便利です。
例えば下記のようなHTMLがあるとします。

<div id="my-site">
  <a href="url">サイトへ飛ぶ</a>
</div>
<div id="another-site">
  <a href="url">サイトへ飛ぶ</a>
</div>

idmy-siteにある「サイトへ飛ぶ」をクリックしたい、と言ったときに使えるのがスコープです。
withinでスコープを指定し、ブロック内で処理をすします。
例えば次のように書きます。

within("div#my-site") do
  click_link 'サイトへ飛ぶ'
end

終わり

改めてまとめながら「なるほど、こうかけば良いのか」と段々理解できてきた気がします。
また、Capybaraとマッチャーがごっちゃになっているなと書きながらわかりました。
他にもたくさんメソッドが用意されているので、使う機会が増えたらパート2という形で公開できたらと考えています。
ご拝読いただきありがとうございました。

参考

GitHub teamcapybara/capybara
Rubyドキュメント Capybara
Capybaraチートシート

Discussion