Storybook 8.2
Storybook 8.2 がリリースされた。テスト機能の改善や、ポータブルストーリーの正式なサポートなどが行われた。 また Storybook 8.3 では、Vitest との統合や互換性の向上が予定されている。
https://storybook.js.org/blog/storybook-8-2/
Portable stories
ポータブルストーリーを介することで、Story をネイティブコンポーネントとして Jest や Vitest、Playwright などで再利用が出来るようになった。
// Button.test.js
import { test, expect } from "vitest";
import { screen } from "@testing-library/react";
import { composeStories } from "@storybook/react";
import * as stories from "./Button.stories";
const { Primary, Secondary } = composeStories(stories);
test("renders primary button with default args", async () => {
await Primary.play();
});Vitest や Jest でポータブルストーリーを利用する方法についてドキュメントが公開されている。
https://storybook.js.org/docs/api/portable-stories/portable-stories-jest?ref=storybookblog.ghost.io
Storybook にテストの責務を持たせたくない場合や、Vitest や Jest の資産を利用したい場合など、非常に便利な機能である。
New test hooks
Jest や Vitest、Playwright、Cypress などとより互換性のあるテストの記述が可能になった。
今まではcanvasオブジェクトを通してのみ Story のテストが可能であったが、mount メソッドが追加され他のテストフレームワークと比較的近い記述が出来るようになった。
// example.stories.tsx
import { fn, expect } from "@storybook/test";
// ...
export const Disabled = {
args: { disabled: true, onSelected: fn() },
play: async ({ mount, args }) => {
// Arrange
const user = useEvent.setup();
const items = await loadItems(10);
const canvas = await mount(<ToolbarMenu items={items} />);
// Act
await user.click(canvas.getByRole("button"));
// Assert
expect(canvas.getAllByRole("button").length).toBe(items.length);
expect(args.onSelected).not.toHaveBeenCalled();
},
};beforeEachやafterEachなどは、Story ファイルの meta に記述する。
// example.stories.tsx
const meta = {
// ...
async beforeEach() {
MockDate.set("2024-02-14");
// Reset the Date after each story
return () => {
MockDate.reset();
};
},
};beforeAllやafterAllは、.storybook/preview.tsに記述する。
// .storybook/preview.ts
import { Preview } from "@storybook/react";
import { init } from "../project-bootstrap";
const preview: Preview = {
async beforeAll() {
await init();
},
};
export default preview;個人的な感想としては、確かに名前が同じフックは生えたが、利用方法にはズレがあり、テストを CSF に変換するための学習曲線は変わらずあるように思う。