BackstopJS
背景
最近、サイト全体で読み込んでいる不要なjsやcssを削除してサイト全体に表示崩れがないか確認する機会が続いたのでビジュアルリグレッションテストをローカルで実行してみました
ビジュアルリグレッションテストとは
ページ全体のスナップショットを撮影して変更前と変更後の画像の差分を検出するテスト
これによって変更後のページで画像崩れなどピクセル単位のズレを検出します
ツール選定
reg-suit をよく耳にしますが、E2EテストをがっつりしたいのではなくサクッとビジュアルリグレッションテストだけをしたかったのでBackstopJSを使用することにしました
導入
$ npm install backstopjs
$ npx backstop init
initするとbackstop.jsonという設定ファイルの雛形とbackstop_dataディレクトリが作成されます
.
├── node_modules
├── package-lock.json
├── package.json
├── backstop.json
└── backstop_data
└── engine_scripts
├── cookies.json
├── imageStub.jpg
├── playwright
│ └── ..省略
└── puppet
├── clickAndHoverHelper.js
├── ignoreCSP.js
├── interceptImages.js
├── loadCookies.js
├── onBefore.js
├── onReady.js
└── overrideCSS.js
設定ファイル
viewports
SPやPCなど複数のviewportを設定できます
label名毎にスナップショットを生成します
"viewports": [
{
"label": "SP",
"width": 375,
"height": 812
},
{
"label": "PC",
"width": 1280,
"height": 800
}
]
scenarios
スナップショットを撮るページを指定します
"scenarios": [
{
"label": "top",
"url": "https://dev.lvnmatch.jp/"
},
{
"label": "sell",
"url": "https://dev.lvnmatch.jp/sell/"
}
],
早速実行
$ npx backstop reference
//特定のラベルのみ実行
$ npx backstop reference --filter=top
上記コマンドを実行するとbackstop_dataディレクトリ配下にbitmaps_referenceディレクトリが作成されてスナップショットが格納されます
bitmaps_reference
├── backstop_default_sell_0_document_0_SP.png
├── backstop_default_sell_0_document_1_PC.png
├── backstop_default_top_0_document_0_SP.png
└── backstop_default_top_0_document_1_PC.png
試しに1ページだけ見出しの文言変更を行います
変更後に以下コマンドにて検証を行います
$ npx backstop test
//特定のラベルのみ実行
$ npx backstop test --filter=top
また、diffも以下のように確認が可能です
その他scenariosの便利なオプション
delay
キャプチャーを撮る前にスリープをかけることができます
removeSelectors / hideSelectors
広告などアクセスする度に画像が変わる要素は、removeSelectorsで削除するかhideSelectorsで非表示にすることができます
hoverSelectors / clickSelectors
ホバー時やクリック後にキャプチャーできます
selectors
ページ全体ではなくページ内の一部のみキャプチャーできます
scrollToSelector
無限スクロールや画像遅延読み込みをしている場合は、scrollToSelectorで特定の要素までスクロールできます
しかし、スクロールスピードが早いのでsmoothスクロールがしたい場合は、scrollToSelectorを使わずにonReadyScriptにsmoothスクロールの記述することも可能です
module.exports = async (page, scenario, vp) => {
console.log('SCENARIO > ' + scenario.label);
await require('./clickAndHoverHelper')(page, scenario);
// add more ready handlers here...
const selector = "footer";
await page.evaluate(selector => {
document.querySelector(selector).scrollIntoView({behavior: "smooth", block: "start"});
}, selector);
};
misMatchThreshold
チャプチャー比較の感度を指定できます
画面内の何%ズレたらテストを失敗にするのか指定できます