RSpecでブラウザのダイアログを操作する方法

ブラウザのダイアログ

Railsエンジニアにはおなじみではありますが(*)、リスクのある操作を行う際に、以下のようなブラウザのダイアログを表示することで確認を促す処理はケースとして良くあることと思います。(画像はGoogle Chromeの例。)
f:id:kazukiyunoue:20180613114850p:plain
今回はそのような処理をRailsでスタンダードなテストフレームワークであるRSpecで実行させたいと思います。(*:Railsの持つ自動コード生成機能が生成するリソース削除の処理が、まさにブラウザのダイアログを表示し、"Are you sure?"と確認を促す流れとなっている。今回の題材もそれ。)

テスト時の環境

ライブラリ バージョン
Ruby 2.5.1
Rails 5.2.0
RSpec 3.6.0
Capybara 3.2.1
Javascript Driver selenium_chrome

実際のコード

require 'rails_helper'

RSpec.feature "Tasks", type: :feature do
  scenario "User can delete a task", js: true do
    create(:task)

    visit tasks_path

    click_link "Destroy", match: :first
    expect {
      page.accept_confirm "Are you sure?"
      expect(page).to have_content "Task was successfully destroyed."
    }.to change { Task.count }.by(-1)
  end
end

pageインスタンスにaccept_confirmとdismiss_confirmというブラウザのダイアログ操作用メソッドが用意されていて、引数にダイアログで表示されるテキスト(今回のケースでは"Are you sure?")を入れることで、該当のダイアログをacceptまたはcancelできるようです。ちなみに"OK"ボタンしか表示されないようなダイアログ用と思われるaccept_alertもあり、今回のケースだとacceptさせたい場合はaccept_alertでも実行できました。RSpecではおなじみのテクニックではありますが、expectのブロック内にひとつ以上のexpectもしくはfindを入れないと、ダイアログが表示されてacceptされる前に次へ進んでしまうので注意が必要です。