Nuxt.jsのサイトにPercyを導入してレンダリング差分を視覚化する


はじめに

Percy はWebページのレンダリング結果の差分を視覚化して、レビューを可能とするサービスです。GitHubと連携させることで、PRを作る度に所定のブランチ(デフォルトではmaster)との差分を抽出し、その結果をPRのステータスへと反映させることができます。そのため、HTMLのマークアップやCSSなどを変更した際に、意図しないリグレッションが発生していないかどうかをチェックするのに有効です。

例えば、CSSを変更したことによって、一部テキストのフォントカラーが変わったとしましょう。左が変更前、右が変更後です。

Percyを使うと、この両者のレンダリング結果の差分を抽出し、次のように異なる箇所をハイライト表示させることができます。

Percyは 月あたり5000以下のスナップショットであれば無料で利用可能 なので、小規模なプロジェクトであれば導入も難しくありません。そこでこの記事では、Percyを用いた差分チェックを可能とする環境の構築方法を説明します。

なお、この記事で紹介するコード、およびセットアップ内容は、GitHubレポジトリ で公開しています。

技術要素

この記事では、以下の技術要素を用います。

  • Nuxt.js / Vue.js
  • Jest / Puppeteer
  • Yarn
  • CircleCI

また、上記の技術要素は既にある程度把握していることを前提とし、個々の詳細な説明は割愛します。

セットアップ

Nuxt.jsサイトの構築

まずはNuxt.jsのサイトを構築します。公式サイトのInstall方法 に従うことで、以下のようなページを表示するNuxt.jsのプロジェクトが作成できるはずです。

Nuxt.jsのプロジェクトを構築後、適切なGitHubレポジトリにソースコードをpushしてください。

テストの構築

Puppeteerのインストール

以下のコマンドをターミナルで実行して、Puppeteer、 Percyの各種パッケージをインストールします。

$ yarn add -D jest jest-puppeteer @percy/puppeteer

Jest/Puppeteerの設定ファイルの追加

以下のようなPuppeteerによるテストのためのJest設定ファイルを配置します。

e2e/jest.config.js
module.exports = {
  moduleFileExtensions: ["js", "json"],
  testRegex: "(/__tests__/.*|(\\.|/)(e2e))\\.js$",
  testPathIgnorePatterns: ["/node_modules/"],
  preset: "jest-puppeteer"
};

また、jest-puppeteerの設定ファイルも以下のように追加します。

jest-puppeteer.config.js
module.exports = {
  server: {
    command: 'yarn start',
    port: 3000
  },
  preset: 'jest-puppeteer'
}

Puppeteerのテストの追加

Puppeteerによるテスト実行、および、Percyのスナップショットを取得するためのテストファイルを配置します。

e2e/website.e2e.js
const puppeteer = require("puppeteer");
const { percySnapshot } = require("@percy/puppeteer");

describe("Web site", () => {
  const BASE_URL = "http://localhost:3000";
  let browser;
  let page;

  beforeAll(async () => {
    browser = await puppeteer.launch();
    page = await browser.newPage();
  });

  afterAll(async () => {
    await browser.close();
  });

  describe("top page", () => {
    beforeAll(async () => {
      await page.goto(BASE_URL);
    });

    it("should show page", async () => {
      await expect(page.title()).resolves.toMatch("nuxt-percy-sample");
      await percySnapshot(page, "Top page");
    });
  });
});

上記テストに記述された percySnapshot が、Percyのスナップショットを取得する関数です。第3パラメータにオプションを渡すことで、以下のようにスナップショット取得時のサイズなどを設定することもできます。

await percySnapshot(page, 'Top page', { widths: [768, 992, 1200] });

percySnapshot のオプションの詳細については、 ドキュメント を参照してください。

package.jsonへのスクリプトの追加

先ほど追加したテストを実行可能とするため、 package.json に、以下のスクリプトを追加します。

package.json
  "scripts": {
    "test:e2e": "jest -c e2e/jest.config.js e2e",
    "test:percy": "percy exec -- yarn test:e2e",
  }

Percyのセットアップ

次にPercyのセットアップを行います。以降の説明は、既にPercyのアカウントとOrganizationが作成してある前提で進めます。

プロジェクトの作成

まずは、現在作成しているコードに対応するPercyのプロジェクトを作ります。プロジェクトの名前は任意のものを指定できますが、わかりやすいようにGitHubのレポジトリ名と同様にしておくのが良いでしょう。

プロジェクトを作成すると、プロジェクト固有のPercyトークンが表示されます。(プロジェクトの設定ページからも確認することができます) これは後のCircleCIのセットアップ作業で使用します。

GitHub Appのインストール

Percyのチェック結果がGitHub PRのステータスに反映されるようにするには、PercyのGitHub Appをインストールする必要があります。そのため、 PercyのGitHub Appのページ からインストールを行ってください。

GitHubレポジトリの連携

先ほど作成したPercyプロジェクトにGitHubレポジトリを紐つけます。Percyプロジェクトの Integrations タブから、以下のようにGitHubレポジトリを選択してください。

CircleCIのセットアップ

最後に、CircleCIのセットアップを行います。

設定ファイルの配置

CircleCIのconfigファイルを .circleci ディレクトリの中に配置してください。なお、CircleCIではPercy用のOrb、 percy/agent が提供されているので、それを利用します。

.circleci/config.yml
version: 2.1

orbs:
  percy: percy/[email protected]

jobs:
  build_test:
    docker:
      - image: circleci/node:12.3-browsers
    working_directory: ~/repo
    steps:
      - checkout
      - run: yarn install
      - run: yarn build
      - run: yarn test:percy

workflows:
  version: 2
  build:
    jobs:
      - build_test
      - percy/finalize_all:
          requires:
            - build_test

CircleCIプロジェクトのセットアップ

上記のconfigファイルをGitHubレポジトリにpushしたら、次にCircleCIをセットアップします。CircleCIプロジェクトの設定は 公式ドキュメント に従って実施するものとし、ここでは詳細を割愛します。

環境変数の設定

先の手順で生成したPercyのトークンをCircleCIに登録します。CircleCIのプロジェクト設定を開いて Environment Variables を選択し、 PERCY_TOKEN という環境変数名でトークンを設定してください。

また、 ドキュメント に従って PERCY_PARALLEL_TOTAL-1 という値も設定しておきます。

CIの実行

ここまでの作業で、セットアップが完了しました。コードを master ブランチにpushしていれば、CircleCIが実行されてPercyへとレンダリング結果がホストされているはずです。

それでは、適当なPRを作って、CircleCI、Percyによるチェック処理を実行させてみましょう。ここでは、下の画像のように、 My laudable Nuxt.js project というテキストのフォントカラーを赤に変更してみます。

この変更をpushしてGitHub PRを作ると、PRのステータスにPercyのチェック結果が表示され、レビューが必要であることが示されます。

上記の Details からPercyへと移動すると、差分を確認することができます。ここでは、フォントカラーを変更した部分がハイライト表示され、レンダリング結果に差分が生じていることが確認できます。

Percyが検出したこの差分をApproveすると、GitHub PRのステータスもOKとなります。

まとめ

この記事では、Nuxt.jsで構築したサイトのレンダリング差分をPercyでチェックするための環境構築についてまとめました。ここではごく基本的な設定しかしていませんが、ドキュメントを見るとわかるように、Storybookとの連携やアニメーションへの対処など、Percyは様々な機能を提供しています。レンダリング結果のリグレッションをチェックする上では有用なサービスだと思うので、導入を検討してみるといいかもしれません。

参考