Ruby on Railsのsystem specで画面ショットを取りつつmasterとの画像比較してVRT的なことできないかなーと思っていたのですが、Capybaraのpage.save_screenshotとreg-cliを使うと実現できそうだったのでメモ📝
ちなみにPlaywrightでは以下の通りtoHaveScreenshot
を使うことで、今回試したような簡単にVRTを実施できます。
madogiwa0124.hatenablog.com
※playwright-ruby-clinetを直接使えば出来るかなと思ったけどtoHaveScreenshot
には現時点では対応していなさそうだった📝
前提事項
- rails (7.1.3.2)
- capybara (3.40.0)
- capybara-playwright-driver (0.5.1)
- 試してないですがplaywrightじゃなくても出来ると思います
実現したいこと
Ruby on Railsのsystem specで画面ショットを取りつつmasterとの差分比較して一定の差異があったら落としたいので、以下のような感じでspec/screenshots
のmasterとcompareに、それぞれmasterのものとトピックで取得した画像ファイルを配置し同一パスのファイルを比較して一定の差異があればエラーにします。
※masterは比較用に初回実行時だけ作成しリポジトリで管理するようにします。(トピックが正になる場合に更新してpushします。)
spec/screenshots
├── compare
│ └── foo
│ └── bar
│ └── baz.png
└── master
└── foo
└── bar
└── baz.png
System Specで任意のタイミングで画面ショットを取得し差分比較用のフォルダに配置する
画面ショットを取得すること自体は、page.save_screenshot(path: Rails.root.join("spec/screenshots/compare/foo/bar/baz")
を実行すればいいのですが、差分比較用のフォルダを毎回してするのは面倒なので以下のようなHeplerを用意していい感じのフォルダに配置できるようにしてみました。
module VrtScreenshotHelper
def vrt_screenshot(page, path:)
return if ENV["GET_SCREENSHOTS_FOR_VRT"] != "true"
base_path = Rails.root.join("spec/screenshots/compare")
page.save_screenshot(base_path.join(path))
end
end
こうすると以下のように取得できます。
it "sample example" do
visit example_path
expect(page).to have_content "sample title"
expect(page).to have_content "sample description"
vrt_screenshot(page, path: "foo/bar/baz.png")
end
初回実行時にはmasterの画面ショットを作成する必要があるので、以下のように変更してmaster側に画面ショットを取得します。
module VrtScreenshotHelper
def vrt_screenshot(page, path:)
return if ENV["GET_SCREENSHOTS_FOR_VRT"] != "true"
- base_path = Rails.root.join("spec/screenshots/compare")
+ base_path = Rails.root.join("spec/screenshots/master")
page.save_screenshot(base_path.join(path))
end
end
取得した画面ショットを比較して一定差分があった場合に落とす
取得した画面ショットを比較して一定差分があった場合に落とすのは以下のreg-cli
を使うと簡単に実現することが出来ました。
github.com
以下のように比較するパスと差分を表す画像の出力先を指定し、レポート出力先-R
、エラーにする閾値-T
を指定することで先ほど保存したスクリーンショットをmasterを比較し、一定の差分があったらレポート付きでエラーにすることが出来ます。
$ reg-cli spec/screenshots/compare spec/screenshots/master spec/screenshots/diff -R spec/screenshots/diff/report.html -T 0.01
上記はspec/screenshots/compare
とspec/screenshots/master
を比較し、差分を示す画像をspec/screenshots/diff
に配置、1%でも差分があればエラーとし、レポートをspec/screenshots/diff/report.html
に吐き出すような指定になります。
実際に実行して失敗すると以下のような出力が表示され差分を検知できます。
$ reg-cli spec/screenshots/compare spec/screenshots/master spec/screenshots/diff -R spec/screenshots/diff/report.html -T 0.01 -U
✘ change spec/screenshots/compare/foo/bar/baz.png
✘ 1 file(s) changed.
差分が発生した場合にはレポートで具体的な差分をブラウザで確認できます。
https://github.com/reg-viz/reg-cli?tab=readme-ov-file#html-report
CircleCIやGitHub Actionでartifactsとして保存するようにすると差分比較がよりしやすくなって良さそうです。
おわりに
reg-cli
あまり使ってことなかったのですが、お手軽に画像比較・レポート作成まで出来て非常に便利ですね ✨