こんにちは!プロダクトデザイナー、そしてエンジニアの皆さん。
日々の開発の中で、こんな絶望を味わったことはありませんか?
「デザイナーがPenpotで完璧に作り込んだレイアウト、余白、タイポグラフィ。しかし、いざエンジニアが実装してブラウザで確認してみたら……なんか違う!ボタンのパディングが狭いし、フォントウェイトも違う気がする!」
そして、こう思うのです。「これを人の目だけでチェックし続けるの、もう限界じゃないか?」と。
デザインと実装の乖離(ズレ)は、プロダクトの品質をじわじわと蝕むサイレントキラーです。特に、オープンソースの強力なデザインツール「Penpot」と、モダンなフロントエンド開発環境(StorybookやWebアプリ)を行き来するチームにおいて、この乖離をどう防ぐかは永遠の課題でした。
今回は、Penpotで作成されたデザインと、実際に実装されたコードの見た目の差異を自動で検知する「Visual Regression Testing(視覚回帰テスト)」の構築方法を徹底解説します。
これをマスターすれば、CI/CDパイプラインが勝手にデザイン崩れを見つけて教えてくれるようになり、毎日の「ここ、直しておいてください」という不毛なやり取りから解放されますよ。さあ、一緒に次世代の堅牢なデザインパイプラインを作りに行きましょう!
—
1. なぜ「Penpot × Playwright」なのか?
まず、今回のアーキテクチャの全体像を整理しておきましょう。
- Penpot: オープンソースのWebベース・デザインツール。CSS GridやFlexboxの概念をそのままデザインに持ち込めるため、エンジニアとの親和性が抜群に高いのが特徴です。
- Playwright: Microsoft製の本番さながらのブラウザ自動化・テストツール。ヘッドレスブラウザで正確なスクリーンショットを撮影できます。
この2つを連携させるアプローチの核心は、「Penpotのエクスポート機能またはAPIでデザインの基準(スナップショット)を得るか、あるいは実装側の正解(Storybookなど)を正本とし、Playwrightでピクセル単位の比較を行う」という点にあります。
一般的には、「デザイナーが作ったPenpot上のコンポーネントの見た目」と「実装されたコンポーネント(Storybook)」のピクセル差分を、CI(GitHub Actionsなど)上でPlaywrightを使って自動比較するパイプラインを構築します。
—
2. 環境構築:まずは第一歩を踏み出そう
それでは、手元のローカル環境にテストパイプラインの土台を作っていきましょう。
Node.js(v18以上推奨)がインストールされている前提で進めます。
プロジェクトの初期化とPlaywrightの導入
適当なディレクトリを作成し、Playwrightをインストールします。
mkdir penpot-vrt-demo
cd penpot-vrt-demo
npm init -y
Playwrightのインストール(TypeScript環境を推奨)
npm init playwright@latest
インタラクティブな質問が表示されますが、基本的にはデフォルト(TypeScript使用、`tests` ディレクトリの作成など)のままで大丈夫です。
これで、プロジェクトのルートに `playwright.config.ts` が生成されます。これがテストの司令塔となります。
—
3. 基礎セットアップ:Playwrightでデザイン崩れを検知する
今回は、Storybookでコンポーネントを管理しているケースを想定して進めましょう(WebアプリのURLでも同様に行えます)。
設定ファイル(`playwright.config.ts`)の調整
まずは、テスト対象のURL(ローカルで動いているStorybookなど)を指定できるように設定を整えます。
import { defineConfig, devices } from ‘@playwright/test’;
export default defineConfig({
testDir: ‘./tests’,
/ テストが失敗した時のスクリーンショット保存設定など /
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: ‘html’,
use: {
// テスト対象のベースURL(例:ローカルのStorybook)
baseURL: ‘http://localhost:6006’,
trace: ‘on-first-retry’,
},
projects: [
{
name: ‘chromium’,
use: { …devices[‘Desktop Chrome’] },
},
],
});
—
4. HelloWorld的動作確認:最初のビジュアルテストを書く
それでは、実際に「デザイン通りの見た目になっているか」を検証するテストコードを書いてみましょう。
`tests/visual-regression.spec.ts` というファイルを作成し、以下のコードを記述してください。
import { test, expect } from ‘@playwright/test’;
test.describe(‘Penpot Design System Visual Regression’, () => {
test(‘Primary Buttonはデザインの意図通りに描画されているか’, async ({ page }) => {
// 1. 検証したいコンポーネントのStorybookのページへ移動
// (例: Buttonコンポーネントの Primary ストーリー)
await page.goto(‘/?path=/story/components-button–primary’);
// 2. 余計なアニメーションやローディングが完了するのを待つ
await page.waitForLoadState(‘networkidle’);
// 3. 対象のコンポーネント要素だけを特定
const buttonElement = page.locator(‘#root’);
// 4. スクリーンショットを撮影し、あらかじめ保存された「正解画像(Baseline)」と比較する
// 初回実行時は比較対象がないためエラーになりますが、自動でベースライン画像が生成されます
expect(await buttonElement.screenshot()).toMatchSnapshot(‘primary-button.png’, {
// 許容するピクセルの色の違い(アンチエイリアスの微差などを許容するため数%設けることもあります)
maxDiffPixelRatio: 0.01,
});
});
});
テストを実行してみよう!
まずはベースライン(正解となる画像)が存在しないため、初回は画像生成モードで実行します。
npx playwright test –update-snapshots
これで、`tests/visual-regression.spec.ts-snapshots/` というフォルダが作成され、中に `primary-button-chromium-darwin.png` のような基準画像が保存されます。これが「Penpotで合意されたデザインの具現化(正解)」です。
次に、わざとCSSを少し崩してみるか、そのままテストを走らせてみましょう。
npx playwright test
見事にテストがパスすれば成功です!
もし、誰かがCSSを書き換えてボタンの角丸や色を変えてしまったら、Playwrightは容赦なくテストを落とし、どこがどう変わったのかを視覚的に示す差分(Diff)レポートを出力してくれます。
—
5. CI/CDパイプラインへの組み込み(GitHub Actions)
ローカルで動くだけではまだ半自動化にすぎません。GitHubにコードをプッシュした際、自動でこのVRT(Visual Regression Testing)が走るように、GitHub Actionsのワークフローを設定しましょう。
プロジェクトのルートに `.github/workflows/vrt.yml` を作成します。
name: Visual Regression Testing
on:
pull_request:
branches: [ main, develop ]
jobs:
visual-test:
runs-on: ubuntu-latest
steps:
- name: 🛑 リポジトリのチェックアウト
uses: actions/checkout@v4
- name: 🟢 Node.jsのセットアップ
uses: actions/setup-node@v4
with:
node-version: 18
cache: ‘npm’
- name: 📦 依存関係のインストール
run: npm ci
- name: 🎭 Playwrightブラウザのインストール
run: npx playwright install –with-deps
- name: 🛠️ Storybook(またはアプリ)のビルドまたは起動
run: |
npm run build-storybook
npx http-server storybook-static -p 6006 &
npx wait-on http://localhost:6006
- name: 📸 ビジュアル回帰テストの実行
run: npx playwright test
- name: 📊 テスト失敗時のレポートアーティファクト保存
uses: actions/upload-artifact@v4
if: failure()
with:
name: playwright-report
path: playwright-report/
retention-days: 30
このパイプラインを組んでおけば、プルリクエストが作成された瞬間に自動で画面の見た目がチェックされ、意図しないデザイン崩れが含まれていた場合はマージできなくなり、品質の砦として機能します。
—
おわりに:デザインとコードの共通言語化へ
今回は、PenpotとPlaywrightを連携させたVisual Regression Testingの基礎を解説しました。
デザインツール上でどれだけ綺麗に整えても、実際のコードに落とし込む段階で崩れてしまうストレスは、エンジニアにとってもデザイナーにとっても大きな負担です。しかし、今回のような自動テストの仕組みを一つ挟むだけで、「見た目の品質」は人の目ではなく、機械が担保してくれるものへと変わります。
これをマスターすれば、毎日の細かなスタイル修正の確認作業から解放され、よりクリエイティブで本質的なプロダクト改善に集中できるようになりますよ。
さあ、あなたのプロジェクトでも、今日からデザインの「自動検品システム」を導入してみませんか?