ビジュアル比較
はじめに
Playwright Testには、await expect(page).toHaveScreenshot()を使用してスクリーンショットを生成し、視覚的に比較する機能が含まれています。初回実行時、Playwright Testは参照スクリーンショットを生成します。その後の実行では、参照と比較されます。
import { test, expect } from '@playwright/test';
test('example test', async ({ page }) => {
await page.goto('https://playwright.dokyumento.jp');
await expect(page).toHaveScreenshot();
});
ブラウザのレンダリングは、ホストOS、バージョン、設定、ハードウェア、電源(バッテリーか電源アダプターか)、ヘッドレスモード、およびその他の要因によって異なる場合があります。一貫性のあるスクリーンショットを得るためには、ベースラインのスクリーンショットが生成されたのと同じ環境でテストを実行してください。
スクリーンショットの生成
上記を初めて実行すると、テストランナーは次のように表示します。
Error: A snapshot doesn't exist at example.spec.ts-snapshots/example-test-1-chromium-darwin.png, writing actual.
これは、まだゴールデンファイルがないためです。このメソッドは、2つの連続したスクリーンショットが一致するまでスクリーンショットを何枚も撮影し、最後のスクリーンショットをファイルシステムに保存しました。これでリポジトリに追加する準備ができました。
ゴールデン期待値のフォルダ名は、テストファイル名で始まります。
drwxr-xr-x 5 user group 160 Jun 4 11:46 .
drwxr-xr-x 6 user group 192 Jun 4 11:45 ..
-rw-r--r-- 1 user group 231 Jun 4 11:16 example.spec.ts
drwxr-xr-x 3 user group 96 Jun 4 11:46 example.spec.ts-snapshots
スナップショット名example-test-1-chromium-darwin.pngはいくつかの部分で構成されています。
-
example-test-1.png- スナップショットの自動生成された名前。toHaveScreenshot()メソッドの最初の引数としてスナップショット名を指定することもできます。await expect(page).toHaveScreenshot('landing.png'); -
chromium-darwin- ブラウザ名とプラットフォーム。レンダリング、フォントなどの違いにより、スクリーンショットはブラウザやプラットフォーム間で異なるため、それぞれに異なるスナップショットが必要になります。設定ファイルで複数のプロジェクトを使用している場合、chromiumの代わりにプロジェクト名が使用されます。
スナップショット名とパスは、Playwrightの設定ファイルでtestConfig.snapshotPathTemplateを使用して設定できます。
toHaveScreenshot()は、expect().toHaveScreenshot(['relative', 'path', 'to', 'snapshot.png'])のように、スナップショットファイルへのパスセグメントの配列も受け入れることに注意してください。ただし、このパスは各テストファイルのスナップショットディレクトリ(つまりa.spec.js-snapshots)内に留まる必要があり、そうでない場合はエラーになります。
スクリーンショットの更新
ページが変更された場合など、参照スクリーンショットを更新する必要がある場合があります。これは、--update-snapshotsフラグを使用して行います。
npx playwright test --update-snapshots
オプション
maxDiffPixels
Playwright Testは、pixelmatchライブラリを使用しています。その動作を変更するために様々なオプションを渡すことができます。
import { test, expect } from '@playwright/test';
test('example test', async ({ page }) => {
await page.goto('https://playwright.dokyumento.jp');
await expect(page).toHaveScreenshot({ maxDiffPixels: 100 });
});
プロジェクト内のすべてのテストでデフォルト値を共有したい場合は、Playwright設定でグローバルに、またはプロジェクトごとに指定できます。
import { defineConfig } from '@playwright/test';
export default defineConfig({
expect: {
toHaveScreenshot: { maxDiffPixels: 100 },
},
});
stylePath
スクリーンショットを撮影する際に、カスタムスタイルシートをページに適用できます。これにより、動的または不安定な要素をフィルタリングし、スクリーンショットの決定論を向上させることができます。
iframe {
visibility: hidden;
}
import { test, expect } from '@playwright/test';
test('example test', async ({ page }) => {
await page.goto('https://playwright.dokyumento.jp');
await expect(page).toHaveScreenshot({ stylePath: path.join(__dirname, 'screenshot.css') });
});
プロジェクト内のすべてのテストでデフォルト値を共有したい場合は、Playwright設定でグローバルに、またはプロジェクトごとに指定できます。
import { defineConfig } from '@playwright/test';
export default defineConfig({
expect: {
toHaveScreenshot: {
stylePath: './screenshot.css'
},
},
});
画像以外のスナップショット
スクリーンショット以外に、expect(value).toMatchSnapshot(snapshotName)を使用してテキストや任意のバイナリデータを比較できます。Playwright Testはコンテンツタイプを自動検出し、適切な比較アルゴリズムを使用します。
ここでは、テキストコンテンツを参照と比較しています。
import { test, expect } from '@playwright/test';
test('example test', async ({ page }) => {
await page.goto('https://playwright.dokyumento.jp');
expect(await page.textContent('.hero__title')).toMatchSnapshot('hero.txt');
});
スナップショットは、テストファイルの隣の別のディレクトリに保存されます。たとえば、my.spec.tsファイルは、my.spec.ts-snapshotsディレクトリにスナップショットを生成して保存します。このディレクトリはバージョン管理(例: git)にコミットし、変更があった場合はレビューする必要があります。