Open2
Next.js + Storybook + Playwrightでスナップショットテストを導入する
作成したページのスナップショットテストを実行する
- 下記コマンドを実行し、
@playwright/test
をプロジェクトにインストールする
npm i -D @playwright/test
- プロジェクトのルートディレクトリに
playwright.config.ts
を追加する
playwright.config.ts
import { devices, PlaywrightTestConfig } from "@playwright/test";
const config: PlaywrightTestConfig = {
use: {
baseURL: "http://127.0.0.1:8080",
},
outputDir: "playwright/out/images",
reporter: [
// スナップショットテストのレポートを生成する
["html", { open: "never", outputFolder: "playwright/out/report" }],
],
webServer: {
// 開発サーバーだとfirefoxのキャプチャーが撮れないことがあるので本番サーバーを起動
command: "npm run start",
url: "http://127.0.0.1:8080",
},
projects: [
// 各端末のスナップショットテストを実行する
{
name: "chromium",
use: { ...devices["Desktop Chrome"] },
},
{
name: "firefox",
use: { ...devices["Desktop Firefox"] },
},
{
name: "safari",
use: { ...devices["Desktop Safari"] },
},
{
name: "iPhone 13",
use: { ...devices["iPhone 13"] },
},
{
name: "iPhone SE",
use: { ...devices["iPhone SE"] },
},
{
name: "iPad Mini",
use: { ...devices["iPad Mini"] },
},
{
name: "iPad Mini landscape",
use: { ...devices["iPad Mini landscape"] },
},
{
name: "Pixel 5",
use: { ...devices["Pixel 5"] },
},
],
};
export default config;
- playwrightディレクトリを作成し、
page-snapshot.spec.ts
を作成する
playwrightpage-snapshot.spec.ts
import { expect, test } from "@playwright/test";
const pagePath = [
// ここに各ページの情報を追加
{
name: "top",
path: "/",
},
];
test.describe.parallel("Visual regression testing of page", () => {
pagePath.map((item) => {
test(`snapshot test ${item.name}`, async ({ page }) => {
await page.goto(item.path);
expect(await page.screenshot({ fullPage: true })).toMatchSnapshot([
item.name,
`${item.name}.png`,
]);
});
});
});
-
package.json
に以下記述を追加する
package.json
<上記略>
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
+ "snapshots:page": "npm run build && playwright test playwright/page-snapshot.spec",
+ "snapshots-update:page": "npm run build && playwright test playwright/page-snapshot.spec --update-snapshots",
},
<下記略>
-
npm run snapshots:page
を実行
ここまで完了すると(pagePathに追加したページの)テストが実行されるはずです。最初の1回目は比較するスクリーンショットが無いことから実行途中でエラーが発生しますが、スクリーンショットの保存には成功するため、2回目以降から正しくスナップショットテストが稼働します。
スナップショットを更新したい場合はnpm run snapshots-update:page
を実行してください。
実際の差分が無いにも関わらず記録されるスクリーンショットの画像サイズが異なるために差分として検知されるなど、safariやfirefox、スマホ端末でのスナップショットは若干不安定なので注意。
githubのissueでも最新バージョンで改善が期待されていました。
Storybookに登録したコンポーネントのスナップショットテストを実行する
- 下記コマンドを実行し、
start-server-and-test
とhttp-server
をインストールする
npm i -D start-server-and-test http-server
- 上記で作成したplaywrightディレクトリに
storybook-snapshot.spec.ts
を作成する
/playwright/storybook-snapshot.spec.ts
import { readFileSync } from "node:fs";
import { resolve } from "node:path";
import { expect, test } from "@playwright/test";
import { StoryIndex } from "@storybook/store";
const storybookDir = resolve(__dirname, "..", "storybook-static");
const data: StoryIndex = JSON.parse(
readFileSync(resolve(storybookDir, "stories.json")).toString()
);
test.describe.parallel("visual regression testing of storybook", () => {
Object.values(data.stories).forEach((story) => {
test(`snapshot test ${story.title}: ${story.name}`, async ({ page }) => {
await page.goto(`http://localhost:8081/iframe.html?id=${story.id}`, {
waitUntil: "networkidle",
});
expect(await page.screenshot({ fullPage: true })).toMatchSnapshot([
story.title,
`${story.id}.png`,
]);
});
});
});
-
storybook/main.js
に以下記述を追加する
.storybook/main.js
module.exports = {
<中略>
+ features: {
+ buildStoriesJson: true,
+ },
};
-
package.json
に以下記述を追加する
package.json
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"snapshots:page": "npm run build && playwright test playwright/page-snapshot.spec",
"snapshots-update:page": "npm run build && playwright test playwright/page-snapshot.spec --update-snapshots",
+ "preview-storybook": "build-storybook && http-server storybook-static/ -p 8081",
+ "snapshots:storybook": "start-server-and-test preview-storybook http://127.0.0.1:8081 'playwright test playwright/storybook-snapshot.spec.ts'",
+ "snapshots-update:storybook": "start-server-and-test preview-storybook http://127.0.0.1:8081 'playwright test playwright/storybook-snapshot.spec.ts --update-snapshots'",
},
-
npm run snapshots:storybook
を実行する。
そうすると、storybookに登録したコンポーネントのスナップショットテストが実行されるはずです(ページのテストと同様、初回は実行中にエラーが発生します)
スナップショットを更新したい場合はnpm run snapshots-update:storybook
を実行してください。