Playwright でビジュアルリグレッションテストを始めてみる

こんにちは、Gaji-Labo アシスタントエンジニアの石垣です。

前回の記事ではビジュアルリグレッションテストツールについて書きました。

今回はVRTツールの新しい選択肢として Playwright というE2E テストのための Node.js フレームワークを社内メンバーに教えてもらったので、触ってみた感触について書いてみたいと思います。

導入

まずは playwright@playwright/test をプロジェクトに導入します。
@playwright/test は Playwright を使用としてテストを作成・実行するテストランナーとしてのライブラリです。

yarn add playwright
yarn add @playwright/test

ビジュアルリグレッションテストを書いてみる

早速テストを書いてみます。
ビジュアルリグレッションテストとしての基本形は以下のようになります。

import { test, expect } from '@playwright/test'
import { webkit } from 'playwright'

test('Visual regression testing of top page', async () => {
  const browser = await webkit.launch()
  const context = await browser.newContext()
  const page = await context.newPage()
  await page.goto('http://localhost:3000/')

  expect(await page.screenshot({ fullPage: true })).toMatchSnapshot()
})

ヘッドレスの Webkit ブラウザを起動し、 http://localhost:3000 に移ってスクリーンショットを撮影する簡単なテストです。

こちらを用意して yarn playwright test を実行するだけでテストができます。

最初の一回はスクリーンショットが無いためテストは失敗します。

Running 1 test using 1 worker
  1) tests/example.spec.mjs:4:1 › Visual regression testing of top page ============================

    Error: /**/tests/example.spec.mjs-snapshots/Visual-regression-testing-of-top-page-1-darwin.png is missing in snapshots, writing actual.

        at **/tests/example.spec.mjs:10:53


  1 failed
    tests/example.spec.mjs:4:1 › Visual regression testing of top page =============================

ここで現在の localhost:3000 がスクリーンショットとして保存されるため、もう一度テストを実行すると通ります。

Running 1 test using 1 worker

  1 passed (4s)

テスト結果のHTMLレポートを生成する

playwright.config.ts を用意して設定を追加することで、テスト結果のHTMLレポートを生成することができます。

import { PlaywrightTestConfig } from '@playwright/test';

const config: PlaywrightTestConfig = {
  reporter: [ ['html', { outputFolder: 'my-report' }] ],
};
export default config;

先程のテストを別のページに変えてみます。

import { test, expect } from '@playwright/test'
import { webkit } from 'playwright'

test('Visual regression testing of top page', async () => {
  const browser = await webkit.launch()
  const context = await browser.newContext()
  const page = await context.newPage()
  await page.goto('http://localhost:3000/about')

  expect(await page.screenshot({ fullPage: true })).toMatchSnapshot()
})

するとテストが失敗した後、HTMLレポートが表示されました。

テスト一覧と合否がHTMLレポートで表示される

複数のブラウザでテストを実行する

複数のブラウザでテストを実行するには playwright.config.ts に projects の設定を追加します。

import { PlaywrightTestConfig, devices } from '@playwright/test';

const config: PlaywrightTestConfig = {
  reporter: [ ['html', { outputFolder: 'my-report' }] ],
  projects: [
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
    },
    {
      name: 'firefox',
      use: { ...devices['Desktop Firefox'] },
    },
    {
      name: 'webkit',
      use: { ...devices['Desktop Safari'] },
    },
    {
      name: 'iPhone 13',
      use: { ...devices['iPhone 13'] },
    },
  ],
};
export default config;

devices はこちらにリストアップされているデバイスを指定することが可能です。
https://github.com/microsoft/playwright/blob/main/packages/playwright-core/src/server/deviceDescriptorsSource.json

設定後、yarn playwright test を実行するだけでそれぞれのデバイスでテストを行えるようになります。

一つのテストに対して使用されたデバイスが色付きで表示される

使ってみた感触

標準で WebKit, Chromium, Firefox, その他デバイスに対応しているのが強い

同じブラウザだけでも差分確認は大変な作業ですが、それに加えブラウザやデバイスによってページの表示が異なることは日常茶飯事です。
Playwright は標準で主要3つのブラウザとその他 iPhone 等のデバイスに対応しているため、各デバイスでの確認作業の省力化に役立ちそうだと感じます。
また Chromium だけ、 WebKit だけというツールもありますが、Playwright は主要ブラウザをきっちりカバーしているのがありがたいところです。

設定が簡単

まださわりしか扱っていない段階ですが、デバイスの追加を playwright.config.ts だけで行えるなど取っつきやすい印象を受けました。
ビジュアルリグレッションテストを行うだけであればすぐに設定が完了できるところも手軽に導入しやすくありがたいです。

おわりに

今回は Playwright でビジュアルリグレッションテストを走らせる方法とその感触についてまとめました。
次回以降で Percy を使ってCIで回してみるなど、より深堀りしていければと思います。

Gaji-Laboでは、UIデザイナーを募集しています

弊社では手ざわりのいいUIを通して事業に貢献したいUIデザイナー、一緒にお仕事をしてくださるパートナーさんの両方を募集しています。大きな制作会社や事業会社とはひと味もふた味も違うGaji-Laboを味わいに来ませんか?

パートナー契約へのお問い合わせもお仕事へのお問い合わせも、どちらもいつでも大歓迎です。まずはオンラインでのリモート面談からはじめましょう。ぜひお気軽にお問い合わせください!

求人応募してみる!

投稿者 Ishigaki Shotaro

アシスタントエンジニアとしてHTML/CSS/JavaScriptの実装やRailsの組み込み、スタイルガイドの構築などを担当しています。 業務の中でさまざまな学びを吸収しながら、文書構造やアクセシビリティに目を向けたマークアップの学習やJavaScriptの学習などを行っています。チームに貢献できるエンジニアとなるために日々奮闘中です。