/
component.test.tsx
97 lines (87 loc) · 3.1 KB
/
component.test.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/// <reference types="vite/client" />
import { Meta, StoryFn, composeStories } from "@storybook/react";
import { render } from "@testing-library/react";
import { describe, test } from "vitest";
declare module "@storybook/types" {
interface Parameters {
vitest?: {
/**
* テストレベルを指定します。
* - `none`: Story をスキップします。(Storybook でのみ実行されます)
* - `smoke-only`: Story のレンダリングのみをテストします。
* - `interaction`: Story のレンダリングとインタラクションをテストします。
*
* @default "interaction"
*/
testLevel?: "none" | "smoke-only" | "interaction" | undefined;
};
}
}
const stories = await Promise.all(
Object.entries(
import.meta.glob<{
default: Meta;
[name: string]: StoryFn | Meta;
}>("../**/*.(stories|story).@(js|jsx|mjs|ts|tsx)", {
eager: true,
}),
).map(async ([path, exports]) => {
const composedStories = composeStories(exports);
return {
path: path.replace(/^\.\.\//, "src/"),
stories: Object.entries(composedStories).map(([name, Component]) => {
const runStory = async () => {
const testLevel =
Component.parameters.vitest?.testLevel ?? "interaction";
// Storybook 7.6 未満または Storybook 7.6 以上で action の定義に `@storybook/test` の `fn()` を使用していない場合は、
// `argTypes` か `actions` を定義し、以下のコードを使用してください。
//
// if (testLevel === "none") {
// return;
// }
//
// const args = Object.fromEntries(
// Object.entries(Component.argTypes ?? {})
// .filter(
// ([name, type]) =>
// // action が定義されているか、
// type.action !== undefined ||
// // prop名が argTypesRegex にマッチする(= `on` で始まる)
// (typeof Component.parameters["actions"]?.argTypesRegex ===
// "string" &&
// new RegExp(
// Component.parameters["actions"].argTypesRegex,
// ).test(name)),
// )
// .map(([name]) => [name, vitest.fn()]),
// );
//
// const screen = render(<Component {...args} />);
//
// if (testLevel === "smoke-only") {
// return;
// }
//
// await Component.play?.({ canvasElement: screen.container, args });
if (testLevel === "none") {
return;
}
const screen = render(<Component />);
if (testLevel === "smoke-only") {
return;
}
await Component.play({ canvasElement: screen.container });
};
return {
name,
runStory,
};
}),
};
}),
);
describe.each(stories)("$path", ({ stories }) => {
test.each(stories)("$name", async ({ runStory }) => {
runStory();
});
});