🥂

LadleとPlaywrightでVisual Regression Testして、さらにはGithubPagesにホスティングした話

2024/02/03に公開

はじめに

コードを見たい方のために、以下Githubのリポジトリ貼っておきます。
ソースコードはこちら
ホスティング
※全然UI作ってないのでサンプル程度に見てください

Ladle is 何 ?

Ladleは、ReactのUIカタログを作成するためのツールです。Ladleを使用すると、Reactコンポーネントをドキュメント化し、コンポーネントの使用方法を示すことができます。Ladleには、Storybookに比べてパフォーマンスが向上し、導入コストが低いという利点があります。

LadleとPlaywrgiht VisualReguressionTestを実装する

公式に、playwrightと統合してVRT(Snapshot)を実装する方法が載っています。
VRTをLadleで動かしたかったので、公式サイトを参考にして作ってみました。
Baseとなるコードはたった25行です。

import { test, expect } from "@playwright/test";
// we can't create tests asynchronously, thus using the sync-fetch lib
import fetch from "sync-fetch";

// URL where Ladle is served
const url = "http://127.0.0.1:61000";

// fetch Ladle's meta file
// https://ladle.dev/docs/meta
const stories = fetch(`${url}/meta.json`).json().stories;

// iterate through stories
Object.keys(stories).forEach((storyKey) => {
  // create a test for each story
  test(`${storyKey} - compare snapshots`, async ({ page }) => {
    // skip stories with `meta.skip` set to true
    test.skip(stories[storyKey].meta.skip, "meta.skip is true");
    // navigate to the story
    await page.goto(`${url}/?story=${storyKey}&mode=preview`);
    // stories are code-splitted, wait for them to be loaded
    await page.waitForSelector("[data-storyloaded]");
    // take a screenshot and compare it with the baseline
    await expect(page).toHaveScreenshot(`${storyKey}.png`);
  });
});

こちらの宣言だけで、playwrightがStorybookの全件を読み取り、UIのスナップショットを撮ってくれます。
ただ、注意点として、playwright.config.tsで以下の通り定義しないと、ladleが起動した状態にならないため、テストを実行しようとしてもタイムアウトします。

import { defineConfig, devices } from "@playwright/test";

export default defineConfig({
  testDir: "./tests",
  ...
  webServer: {
    command: process.env.TYPE === "dev" ? "pnpm serve" : "pnpm build",
    url: `http://127.0.0.1:61000`,
    // reuseExistingServer: true,
  },
});

package.json(こちらは公式と同じです)

{
...
  "scripts": {
    "serve": "ladle serve",
    "build": "ladle build",
    "test:dev": "TYPE=dev pnpm exec playwright test",
    "test": "pnpm exec playwright test",
    "test:update": "pnpm exec playwright test -u"
  },
...
}

合わせてvite.config.tsも設定が必要でした

export default {
  server: {
    open: "none",
    host: "127.0.0.1",
  },
  preview: {
    open: "none",
    host: "127.0.0.1",
  },
};

この辺りはWorkingExampleを見つつ進めるのが良いかと思います。

いよいよGithubPagesにHosting

以下二点を設定する必要があります

package.jsonに"homepage"を設定

変数部分{GITHUB_NAME}と{REPO_NAME}は適宜置き換えてください。

{
...
  "homepage": "https://${GITHUB_NAME}.github.io/${REPO_NAME}"
}

.ladle/config.mjsの設定

以下のように、${REPO_NAME}を指定してください
ここの設定ができていないと、デプロイが成功してもホワイトアウトした状態でPageが表示されます。

/** @type {import('@ladle/react').UserConfig} */
export default {
  base: "/ladle", // ${REPO_NAME}
};

エビデンスはViteのgithub pagesの設定です。

ladleはviteで動いているらしく、また.ladle/config.mjsはvite.config.tsをオーバーライドします。
そのため、.ladle/config.mjsの設定がvite.config.tsの設定として反映され、期待する結果になる因果関係のようです。

GithubPagesの設定

GithubPages公式を参考に、僕は
ブランチ:main
ディレクトリ:docs
のあるリソースをデプロイするように設定してます。

デプロイコマンド

こちらの記事を参考にさせていただきました。

{
...
  "scripts": {
...
    "predeploy": "npm run build",
    "git": "git add . && git commit -m 'deploy' && git push origin main",
    "deploy": "npm run rm && npm run build && npm run mv && npm run git",
    "rm": "rm -rf docs",
    "mv": "mv build docs",
...
  },
 ...
}

上記のようにscriptsを定義して

npm run deploy

でデプロイが完了し、docsディレクトリにbuildしたファイルが配置されます。

さいごに

仕事で最近LadleとPlaywrightを使ってVRTを導入し、差分が出た時に検知できる仕組みがあると何かと便利だな〜と思いました。
ただ、UI側はデザイナーさんともコミュニケーションしたくなる部分なので、コンポーネントカタログの作成からVRT、さらにHostingまで一気通貫で記事にしてみました。

GithubPagesは基本Publicに公開されるので(EnterpriseだとPrivateアクセスにできるっぽい)、業務で使用する際には注意が必要かもしれませんが、開発における品質担保とエンジニア・デザイナー横断でのUIに関するコミュニケーションの基盤として参考にしていただければ幸いです。

Discussion